Annotate concept

Java annotations are an Annotation mechanism introduced in JDK5.0. Java annotations are used to provide metadata to Java code. As metadata, annotations don’t directly affect your code execution, but there are some types of annotations that can actually be used for this purpose. Annotations can be thought of as an extended template for a class/method that handles different logic according to the rules in the annotation class.


The role of annotations:

  • Document: Generate documentation from annotations identified in code
  • Compilation checks: Enable the compiler to perform basic compilation checks through annotations identified in the code
  • Code analysis: Analysis of code by the annotations identified in the code

Java annotations make it possible to use one or more annotations instead of a lot of configuration files and logic, making programming simpler and code cleaner. Java annotations are widely used in framework code such as Spring Boot.


The three most commonly used comments are:

  • Override – the compiler check tells the compiler that this is a method that overrides the parent class. If the parent removes the method, the subclass will report an error.
  • Deprecated – A compilation check indicating that the annotated element is Deprecated.
  • @SuppressWarnings – A compile check that tells the compiler to ignore warnings.


A little confused? That’s all right. Take a look.


As we know, @deprecated indicates that the annotated element has been Deprecated. The function getString2() below is not modified by @deprecated and is called normally. GetString1 () is modified by @deprecated, and IDEA is automatically underlined when called, indicating that this function is not recommended. This is the compile check function of annotations.


Some people ask how @deprecated is implemented, so let’s look at the source code for @deprecated.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}Copy the code

We see that Deprecated is modified with @interface to indicate that Deprecated is a Java annotation. Let’s decompile this code and get

public interface Deprecated extends java.lang.annotation.Annotation {}Copy the code

As you can see, the essence of the annotation is an interface, the interface default inherited Java lang. The annotation. The annotation interface.


Yuan notes

“Deprecated” is a note. Why does it have a note at the top? What the hell is @Retention @Target?

@Retention and @target are both called meta-annotations. Meta-annotations can be interpreted as annotations for annotations, which are used in annotations to facilitate the implementation of desired functions. Meta annotations include @Retention, @target, @document, @Inherited and @REPEATable (added in JDK1.8).

@Retention

  • @Retention indicates the lifetime of annotations, whether they are retained at source (compile-time), bytecode (class-loading), or runtime (running in the JVM). Use the enumeration RetentionPolicy in the @Retention annotation to indicate the annotation Retention period
  • @Retention(retentionPolicy.source), annotations exist only in the SOURCE code and are not included in class bytecode files
  • @Retention(retentionPolicy.class), the default Retention policy. Annotations are present in the CLASS bytecode file but not available at runtime
  • @Retention(retentionPolicy.runtime), annotations are stored in class bytecode files and can be retrieved by reflection at RUNTIME
  • Custom annotations must select @Retention(retentionPolicy.runtime)

@Target

  • The @target meta-annotation indicates the scope of our annotation, which can be class, method, method parameter variables, etc., as well as the type of the annotation expressed by enumerating the class ElementType
  • @target (elementType.type) functions on interfaces, classes, enumerations, and annotations
  • @target (elementType. FIELD) a constant used for attribute fields and enumerations
  • @target (ElementType.METHOD) Specifies the action METHOD
  • @target (elementtype.parameter) acts on method parameters
  • @target (elementtype.constructor) acts on the CONSTRUCTOR
  • @target (elementType.local_variable) acts on local variables
  • @target (elementType.annotation_type) applies to annotations (this property is used in the @retention annotation)
  • @target (elementType.package) applies to packages
  • @target (elementtype.type_parameter) applies to type generics, i.e. generic methods, generic classes, generic interfaces (added in JDk1.8)
  • The @target (elementType.type_use) type is used. Can be used to annotate any type except class (added in JDk1.8)

@Documented

  • Document means Document. It provides the ability to include elements from annotations into Javadoc.

@Inherited

  • Inherited means inheritance, but this is very similar to the way we understand inheritance. An annotation annotated by @Inherited modifs a parent class, and if the child class is not annotated by other annotations, the child class inherits the parent class.

@Repeatable

  • Repeatable means Repeatable in English. As the name implies, an annotation modified by this meta-annotation can apply to an object more than once, but each annotation can represent a different meaning.

Annotation properties

Annotations have only member variables and no methods. Below we define a method annotation that applies to a method with two attributes, name and age.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String name() default "sheldon";
    int age();
}Copy the code

Assign to the attribute in the annotation, because name already has a default value of Sheldon, so you only need to assign to age as follows.

public class Student {
    @MyAnnotation(age = 26)
    public void test(a) {}}Copy the code

Get annotation properties

Getting annotation properties is the key to using annotations, and the method of getting annotation properties is based on reflection. For those unfamiliar with reflection, refer to Java Reflection – the soul of frame design.

public class AnnotationTest {
    public static void main(String[] args) throws Exception { Class<? > studentClass = Student.class; Method method = studentClass.getMethod("test");
        // Determine if the @myAnnotation annotation exists on the test() method
        boolean isPresent = method.isAnnotationPresent(MyAnnotation.class);
        if (isPresent) {
            // Print out the value of the attribute in the annotation if it existsMyAnnotation annotation = method.getAnnotation(MyAnnotation.class); System.out.println(annotation.name()); System.out.println(annotation.age()); }}}Copy the code

The output

sheldon
26Copy the code

Apply – Make logical judgments

Now that we can get the attribute value of the annotation, we can make a logical judgment. Let’s look at an example of a bank transfer. Suppose the bank has a transfer service, and the transfer limit may change according to the exchange rate. We can use annotations to flexibly configure the transfer limit without changing our business code every time.

/** Define quota annotations */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BankTransferMoney {
    double maxMoney(a) default 10000;
}
/** transfer processing business */
public class BankService {
    / * * *@paramMoney Transfer amount */
    @BankTransferMoney(maxMoney = 15000)
    public static void TransferMoney(double money){
        System.out.println(processAnnotationMoney(money));

    }
    private static String processAnnotationMoney(double money) {
        try {
            Method transferMoney = BankService.class.getDeclaredMethod("TransferMoney".double.class);
            boolean annotationPresent = transferMoney.isAnnotationPresent(BankTransferMoney.class);
            if(annotationPresent){
                BankTransferMoney annotation = transferMoney.getAnnotation(BankTransferMoney.class);
                double l = annotation.maxMoney();
                if(money>l){
                   return "Transfer amount exceeds limit, transfer failed";
                }else {
                    return"The amount of transfer is :"+money+", the transfer is successful"; }}}catch ( NoSuchMethodException e) {
            e.printStackTrace();
        }
        return "Transfer processing failed";
    }
    public static void main(String[] args){
        TransferMoney(10000); }}Copy the code

The output

The transfer amount is: 10000.0, the transfer is successfulCopy the code


reference

Java annotations (annotations) (www.runoob.com/w3cnote/jav.)

Java annotations complete solution (www.jianshu.com/p/9471d6bcf.)