Home  >  Article  >  Java  >  Detailed examples of annotation mechanism and principles in Java

Detailed examples of annotation mechanism and principles in Java

黄舟
黄舟Original
2017-10-14 09:43:321109browse

This article mainly introduces relevant information about the annotation mechanism and its principles in Java. I hope this article can help everyone understand and master this part of the content. Friends in need can refer to it

Detailed explanation of the annotation mechanism and its principles in java

What are annotations

Annotations are also called metadata, such as our common @Override and @ Deprecated, annotation is a feature introduced in JDK1.5 version. It is used to explain the code. It can annotate packages, classes, interfaces, fields, method parameters, local variables, etc. Its main functions are as follows:

  • Generate documents and generate javadoc documents through the metadata identified in the code.

  • Compilation check allows the compiler to check and verify during compilation through the metadata identified in the code.

  • Dynamic processing at compile time. Dynamic processing at compile time through the metadata identified in the code, such as dynamically generating code.

  • Dynamic processing at runtime. Dynamic processing at runtime through the metadata identified in the code, such as using reflection injection instances.

General annotations can be divided into three categories:

  • The first category is the standard annotations that come with Java, including @Override, @ Deprecated and @SuppressWarnings are used to indicate overriding a method, indicating that a certain class or method is obsolete, and indicating warnings to be ignored. The compiler will check after being marked with these annotations.

  • The first category is meta-annotations. Meta-annotations are annotations used to define annotations, including @Retention, @Target, @Inherited, @Documented, and @Retention is used to indicate that annotations are retained. stage, @Target is used to indicate the scope of use of annotations, @Inherited is used to indicate that annotations can be inherited, and @Documented is used to indicate whether to generate javadoc documents.

  • The first category is custom annotations. You can define annotations according to your own needs, and you can annotate custom annotations with meta-annotations.

Use of annotations

The use of annotations is very simple. You only need to mark an annotation where an annotation is required. For example, annotate the method:


public class Test {
  @Override
  public String tostring() {
    return "override it";
  }
}

For example, annotate on the class:


@Deprecated
public class Test {
}

So Java’s built-in annotations can be used directly, but there are many Sometimes we need to define some annotations ourselves. For example, common spring uses a large number of annotations to manage dependencies between objects. Let's take a look at how to define your own annotation. Let's implement such an annotation: inject a string into a certain class through @Test, and inject a string into a certain method through @TestMethod.

①Create a Test annotation, declare it to act on the class and retain it until runtime. The default value is default.


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
  String value() default "default";
}

② Create a TestMethod annotation, declare it to act on the method and retain it until runtime.


@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TestMethod {
  String value();
}

③The test class outputs two strings, default and tomcat-method, after running. Because @Test does not pass in a value, the default value is output, and @TestMethod The injected string is output.


@Test()
public class AnnotationTest {
  @TestMethod("tomcat-method")
  public void test(){
  }
  public static void main(String[] args){
    Test t = AnnotationTest.class.getAnnotation(Test.class);
    System.out.println(t.value());
    TestMethod tm = null;
    try {
      tm = AnnotationTest.class.getDeclaredMethod("test",null).getAnnotation(TestMethod.class);
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println(tm.value());
  }
}

The principle of annotations

The previous article introduced how to use Java’s built-in annotations and how to customize an annotation. Let’s read on. Let’s look at the principles of annotation implementation and see how annotations are supported under the larger Java system. Let’s go back to the custom annotation example above. For the annotation Test, as follows, if the AnnotationTest class is annotated, the value of the annotation declaration can be obtained at runtime through AnnotationTest.class.getAnnotation(Test.class). From the above sentence, you can It can be seen that it obtains the Test annotation from the class structure, so the annotation must have been added to the class structure at some point.


@Test("test")
public class AnnotationTest {
  public void test(){
  }
}

The conversion from java source code to class bytecode is completed by the compiler. The compiler will parse the java source code and generate class files, and the annotations are also compiled during compilation. It is processed by the compiler. The compiler will process the annotation symbols and append them to the class structure. According to the JVM specification, the class file structure is a strictly ordered format. The only way to append information to the class structure is to save it to the class structure. attributes attribute. We know that classes, fields, and methods have their own specific table structures in the class structure, and each has its own attributes. As for annotations, their scope of action can also be different. They can be applied to classes or to On a field or method, the compiler will store the annotation information in the properties of the class, field, or method.

After our AnnotationTest class is compiled, the corresponding AnnotationTest.class file will contain a RuntimeVisibleAnnotations attribute. Since this annotation is applied to the class, this attribute is added to the attribute set of the class. That is, the key-value pair value=test of the Test annotation will be recorded. When the JVM loads the AnnotationTest.class file bytecode, it will save the RuntimeVisibleAnnotations attribute value to the Class object of AnnotationTest, so the Test annotation object can be obtained through AnnotationTest.class.getAnnotation(Test.class), and then through The Test annotation object obtains the attribute values ​​​​in Test.

You may have questions here, what is the Test annotation object? In fact, the essence of the compiled annotation is an interface that inherits the Annotation interface, so @Test is actually "public interface Test extends Annotation". When we call it through AnnotationTest.class.getAnnotation(Test.class), the JDK will generate it through a dynamic proxy An object that implements the Test interface, and sets the RuntimeVisibleAnnotations attribute value into this object. This object is the Test annotation object, and the annotation value can be obtained through its value() method.

The entire process of Java annotation implementation mechanism is as shown above. Its implementation requires the cooperation of the compiler and JVM.

The above is the detailed content of Detailed examples of annotation mechanism and principles in Java. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn