Detailed explanation of Java annotations

  • What is annotation?

Java annotation, also known as Java annotation, is an annotation mechanism introduced by JDK5.0. For example, our common @Override and @Deprecated are annotations, which can be added to classes, methods, member variables, etc., similar to "labeling" them.

  • How to define annotation?

Public @interface annotation name {} looks very similar to defining an interface, except for an additional @ symbol interface: public interface interface name annotation: public @interface annotation name

public @interface myapt{
    
}
  • How to use annotations?

Now that our annotation has been defined, the "@ annotation name" can be used directly. For example, we can define it on "class, member variable and member method" below:

Now the annotation has been defined and used, but I don't want to define it on classes and member methods, just on member methods. How can I make the annotation only define on methods and report errors elsewhere? Desired effect:

At this time, we need to use meta annotations to limit the scope.

  • Meta annotation

Generally speaking, meta annotations are annotations defined on annotations. In Java, there are four meta annotations @Target @Retention @Documented @Inherited

  • @Target

@Target is the definition range used to describe the annotation, which can limit the element types defined by this annotation.

parametereffect
ElementType.ANNOTATION_TYPECan be applied to annotation types
ElementType.CONSTRUCTORCan be applied to constructors
ElementType.FIELDCan be applied to fields or attributes
ElementType.LOCAL_VARIABLECan be applied to local variables
ElementType.METHODCan be applied to method level annotations
ElementType.PACKAGECan be applied to package declarations
ElementType.PARAMETERParameters that can be applied to methods
ElementType.TYPECan be applied to any element of a class

To limit the definition to member variables, we should use elementtype FIELD

@Target({ElementType.FIELD,ElementType.METHOD})
public @interface myapt {

}
  • @Retention

@Retention is used to define the life cycle of annotations, which can also be understood as storage mode.

parametereffect
RetentionPolicy.SOURCEThe annotation of the tag remains only at the source level and is ignored by the compiler
RetentionPolicy.CLASSMarked annotations are retained by the compiler at compile time, but are ignored by the Java virtual machine (JVM)
RetentionPolicy.RUNTIMEThe annotation of the tag is reserved by the JVM, so it can be used by the runtime environment

The following two meta annotations are not used much and will not be explained in detail for the time being

  • @Documented

@Documented is used to describe whether annotation information should be retained when generating help documents.

  • @Inherited

@Inherited is used to describe whether the annotation modified by it is inherited.

  • Annotation element

We just defined an annotation above, but we can't pass any information. It's just equivalent to a tag. Now let's see how to define parameters for the annotation:

@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface lkx {
    String name() default "Zhang San"; //You can use default to define the default value
    int age();
}

  • matters needing attention:

  1. The following code needs reflection. If you don't know it yet, you can see my previous articles.
  2. Because you want to get annotation parameters with reflection, @Retention needs to be defined as retentionpolicy RUNTIME

Implementation code:

public class APTTest {


    @Target({ElementType.FIELD,ElementType.METHOD}) -----//Define who annotations can only be used by
    @Retention(RetentionPolicy.RUNTIME)
    public @interface myapt{

         String b() default "dvalue";  ----- //Default dvalue
         int a();
    }

 
    @myapt(age = 18)  ---------  //Can be used to pass parameters
    private static int bl1;

    @myapt(name = "test2",age = 38)
    private static String bl2;

    public static void main(String[] args) throws Exception {


        APTTest tt = new APTTest();
        System.out.println("Before assignment: bl1: " + bl1+"   bl2: "+bl2);

        //Get the bytecode of the class
        Class<Test> testClass = APTTest.class;
        //Get all member variables
        for (Field declaredField : testClass.getDeclaredFields()) {
            //Detect whether there is an annotation of "we define" on the member variable
            if (declaredField.isAnnotationPresent(lkx.class)) {

                myapt annotation = declaredField.getAnnotation(lkx.class);
                //Get the value of in the annotation
                int tmpa = annotation.a();
                String tmpb = annotation.b();

     System.out.println("adopt for Loop to get the variables in the class a+ " + tmpa + ", b:"+ b );

                //declaredField.set(testClass.newInstance(),age);
                //declaredField.set(tt,age);
            }
        }

   
    }
}

@BindView(R.id.groupChat)
Button mGroupChat;

@BindView(R.id.privateChat)
Button mPrivateChat;

Note: because annotations use reflection mechanism, it will affect "performance"

Startup performance, execution performance

You can have a look

butterknife framework

Source code of viewbing

Tags: Java jvm programming language

Posted by adamb10 on Sun, 03 Jul 2022 01:09:20 +0530