This is the second day of my participation in the More text Challenge. For more details, see more text Challenge

1. What are annotations?

Java annotations, also known as Java annotations, are a kind of Annotation mechanism introduced by JDK5.0. Annotations are a form of metadata that provides data about the program but does not belong to the program itself. Annotations have no direct impact on the code they annotate. How do you understand that? It’s literally, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation, it’s a annotation.

2. Definition of annotations

All annotations in Java implement the Annotation interface by default:

package java.lang.annotation;

public interface Annotation {
    boolean equals(Object var1);

    int hashCode(a);

    String toString(a);

    Class<? extends Annotation> annotationType();
}
Copy the code

3. Meta annotations

Meta-annotations: When defining an annotation, an annotation class can also use other annotation declarations. An annotation class that annotates an annotation type is called meta-annotations. There are usually two meta-annotations that need to be specified when defining a custom annotation

The two metannotations are @Documented and @inherited. The former is used to be extracted into documentation by the Javadoc tool, and the latter indicates that a child class is allowed to integrate annotations defined in the parent class

The @Target annotation tags another annotation to limit the types of Java elements to which the annotation can be applied. The target annotation specifies one of the following element types as its value

  • Elementtype. TYPE for any element of a class (class, interface, annotation, enumeration)
  • Elementtype. FIELD applies to a FIELD or property
  • Elementtype. METHOD applies to METHOD level annotations
  • Elementtype.parameter Is the PARAMETER applied to the method
  • Elementtype. CONSTRUCTOR is used for constructors
  • Elementtype. LOCAL_VARIABLE applies to local variables
  • Elementtype. ANNOTATION_TYPE applies to annotation types
  • Elementtype. PACKAGE applies to PACKAGE declarations

The @Retention annotation specifies how the annotation is stored and when the annotation is in effect

  • The retentionPolicy.source tag annotations remain at the SOURCE level only and are ignored by the compiler
  • The retentionPolicy.class tag annotations are retained by the compiler at compile time and ignored by a single JVM
  • The retentionPolicy.Runtime convenient annotation is retained by the JVM, so it can be used by the RUNTIME environment

When the compiler is retained, it is also used at the SOURCE level, not only at compile time. The same is true for RUNTIME, which includes the SOURCE and CLASS phases

4. Customize an annotation

In meta-annotations, we saw that while it is possible to pass parameters when using annotations, we can also pass parameters in custom annotations (having the body of the custom annotation contain an Annotation Type Element declaration) that look like methods and can define optional default values

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS) // Annotations are retained until compile time
@Target({ElementType.TYPE,ElementType.FIELD})// Apply the element and attribute fields of the class
public @interface BindView {
    String value(a);// There is no default value
    int age(a) default  1; // There are default values
}

Copy the code

use

public class MainActivity extends AppCompatActivity {
// @BindView("amszlk")
    @BindView(value = "amszlk",age=10)
    private String name;
}
Copy the code

When using an annotation, you must pass a value if the type element in the defined annotation does not have a default value

5. Annotate the application scenario

According to the @Retention meta-annotation, annotations can be used in three scenarios

5.1 SOURCE: SOURCE level annotations can be provided for IDE syntax checking, APT and other scenarios

5.1.1 IDE syntax check

In Android development, the @intDEF annotation is provided in both support-annotation and AndroidX. annotation, which is defined below

@Retention(SOURCE)// Source level annotations
@Target({ANNOTATION_TYPE})
public @interface IntDef {
    /** Defines the allowed constants for this element */
    int[] value() default {};

    /** Defines whether the constants can be used as a flag, or just as an enum (the default) */
    boolean flag(a) default false;

    /** * Whether any other values are allowed. Normally this is * not the case, but this allows you to specify a set of * expected constants, which helps code completion in the IDE * and documentation generation and so on, but without * flagging compilation warnings if other values are specified. */
    boolean open(a) default false;
}

Copy the code

At runtime, all enumerated classes are loaded into memory as singleton, which is 5 to 10 times more memory than a constant. The significance of this annotation is that it can replace enumeration and implement method entry restriction examples: So we’re going to define a method, test, which is going to take a parameter and the coder has to choose between Java and JavaScript

public enum Coder {
    JAVA,JAVASCRIPT
}
public void test(Coder coder){}Copy the code

We are now not using enumerations for memory optimization purposes

public class Test {
    public static  final  int JAVA=1;
    public static final int JAVASCRIPT=2;
    
   public void test(int coder){}}Copy the code

At this point, however, we call the test method, which cannot be type qualified because we are using test, and can pass numbers other than 1 and 2. This is where we can add custom annotations with @intDef

    @IntDef(value={JAVA,JAVASCRIPT})// Limited to JAVA and JAVASCRIPT
    @Target(ElementType.PARAMETER)// On the parameter
    @Retention(RetentionPolicy.SOURCE)// Source level annotations
    public @interface Coder {
    }
   public void test(@Coder int coder){}Copy the code

This will result in an error if you pass arguments that are not JAVA or JAVASCRIPT

5.1.2APT annotation processor

APT: Java source files are compiled by JavAC and translated into bytecode files that the VIRTUAL machine can load and parse. The Annotation Processor is a tool that comes with JavAC. Used to process annotation information at compile time. You can register your own annotation handler for certain annotations. The registered annotation handler is invoked by JavAC and passes the annotation information to the annotation handler for processing. Glide, ARouter, ButterKnifer, Tinker, EventBus and other frameworks have annotation processors. These frameworks define annotations not at the Source level, but more at the Class level, because the Class level includes the Source level

5.2 the CLASS

Annotations defined as CLASS are retained in the CLASS file, but are ignored by the VIRTUAL machine. That is, the annotations cannot be reflected at run time. The scenario where this annotation is fully applicable is for bytecode operations, such as hot fix Roubust: Modifying the bytecode class file directly to modify the execution logic of the code. For example: Login interception, there’s a lot of things in our program that we need to do to determine whether or not we’re logging in, whether or not we’re logging in, whether or not we’re logging in, whether or not we’re logging in, if we’re logging in, if we’re logging in, if we’re logging in without logging in, if we’re using normal coding, we’re putting an if else judgment in a lot of methods, but with CLASS period annotations, we can use AOP, Divide all function points in the program into two sections that require login and those that do not, and use annotations to distinguish the sections

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.CLASS)
    public @interface Login{
        
    }
    @Login
    public void jumpAActivity(a){}public void jumpBActivity(a){}Copy the code

In the above code, we can take the method annotated Login in the compiled bytecode of the class, and then manipulate the bytecode, modify the contents of the class, and add an if else

/ / the Class files
@Login
public void jumpAActivity(a){
	if(this.isLogin)  {
		this.startActivity(new Intent(this,LogingActivity.class))
	} else {
		this.startActivity(new Intent(this,AActivity.class))
	}     
 } 
Copy the code

5.3 the RUNTIME

Annotations are retained until runtime, meaning that we can combine reflection techniques at runtime to get all the information in the annotations

6. Summary

This article from the definition of annotations, use and use of the scenarios of annotations to learn again, later will be combined with other technologies to learn, learn technology can not only learn and learn, we have to put them on the ground, practice! Come on together! Hope the big guys one key three!