-
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.
parameter | effect |
---|---|
ElementType.ANNOTATION_TYPE | Can be applied to annotation types |
ElementType.CONSTRUCTOR | Can be applied to constructors |
ElementType.FIELD | Can be applied to fields or attributes |
ElementType.LOCAL_VARIABLE | Can be applied to local variables |
ElementType.METHOD | Can be applied to method level annotations |
ElementType.PACKAGE | Can be applied to package declarations |
ElementType.PARAMETER | Parameters that can be applied to methods |
ElementType.TYPE | Can 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.
parameter | effect |
---|---|
RetentionPolicy.SOURCE | The annotation of the tag remains only at the source level and is ignored by the compiler |
RetentionPolicy.CLASS | Marked annotations are retained by the compiler at compile time, but are ignored by the Java virtual machine (JVM) |
RetentionPolicy.RUNTIME | The 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:
- The following code needs reflection. If you don't know it yet, you can see my previous articles.
- 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