May you be like sunshine, bright and not sad.
1. What is annotation
Annotation is also called metadata (information describing data attributes) is represented by @ interface. It is a code level description. It is a feature introduced in JDK1.5 and later versions. It is at the same level as classes, interfaces and enumerations. It can be declared in front of packages, classes, fields, methods, local variables, method parameters, etc. to describe and annotate these elements. In short, annotation is actually Special tags in the code, which can be read during compilation, class loading and runtime, and perform corresponding processing to facilitate supplementary information or deployment of other tools. But annotations do not change the logic of the code.
2. Meta annotations provided by Java (useful in user-defined annotations in Section 4)
The function of meta annotation is to annotate other annotations. Java 5.0 defines four standard meta annotation types, which are used to describe other annotation types. These types and the classes they support can be found in the java.lang.annotation package.
annotations | explain |
---|---|
Target | Object scope: packages, types, type members, method parameters, local variables |
Retention | Retention period: source code retention, class retention (default), runtime retention |
Documented | Document: the modified annotation class will be extracted into a document by Javadoc tool, and the document attributes not supported by Javadoc can be customized |
Inherited | Inheritance: the parent class annotation will be inherited by the child class. If a parent class uses @ Xxx, its child class will be automatically modified by @ Xxx (only valid when @ Target is defined as ElementType.TYPE) |
Repeatable(1.8) | Repeatable: it means that the same annotation is repeated at the same position, which is equivalent to a container annotation (array) |
Native(1.8) | Local: a field that defines a constant value can be referenced from local code (the field is a constant) |
- Example
******************* @Target - ElementType ****************** /* The values (ElementType) are: 1.CONSTRUCTOR:Used to describe constructors 2.FIELD:Used to describe attributes 3.LOCAL_VARIABLE:Used to describe local variables 4.METHOD:Used to describe the method 5.PACKAGE:Used to describe the package 6.PARAMETER:Used to describe parameters 7.TYPE:Used to describe a class, interface (including annotation types), or enum declaration 8.ANNOTATION_TYPE:Used to annotate an annotation 9.TYPE_PARAMETER(1.8)In a declaration statement for a type variable 10.TYPE_USE(1.8)In any statement used to label the type (excluding class) 11.MODULE(9)For module declaration */ ******************* @Retention - RetenionPolicy ******************* /* The values (RetenionPolicy) are: 1.CLASS The compiler records the annotation in the class file. You can do some processing actions according to the annotation during compilation, but the runtime JVM (Java virtual machine) will ignore it and we can't read it during runtime. This is the default value! 2.RUNTIME The compiler records the annotation in the class file. When running a java program, the JVM can obtain annotation information, and the program can obtain the annotation information through reflection. Almost all custom annotations in actual development use retentionpolicy RUNTIME 3.SOURCE The annotation is only saved in the source code. The compiler directly discards the annotation. This annotation has the same effect as an annotation and can only be seen by those reading Java files */ package com.example.annotation.controller; import java.lang.annotation.*; public class MetaAnnotation { @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) @Documented @Inherited public @interface Demo { // You can specify initial values for member variables public String value() default ""; } @Target({ElementType.PACKAGE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface DemoTable { public String tableName() default "className"; } @interface Persons { Person[] value(); } @Repeatable(Persons.class) @interface Person { String role() default ""; } @Person(role = "IT") @Person(role = "God") @Person(role = "Road") public class SuperMan { } }
3. Basic built-in annotations provided by Java
annotations | explain |
---|---|
Override | Restricted parent class override method: when a child class overrides a parent class method, the child class can add this annotation to ensure that the child class does override the parent class method and avoid low-level errors |
Deprecated | Mark obsolete: indicates that a program element, class, method, etc. are obsolete. When other programs use obsolete classes and methods, the compiler will give a warning (delete line) |
SuppressWarnings | Suppress compiler warnings: suppresses compiler warnings for elements modified by the annotation and all child elements of the element |
SafeVarargs | Containment reactor contamination warning 1 : tells the compiler that generics in variable length arguments are type safe |
FunctionalInterface | Functional interface 2 : it is used to specify that the interface is a functional interface and ensure that the interface has only one abstract method, which is convenient for conversion to Lambda expression |
- Example
******************* @SuppressWarnings - Arguments ****************** /* 1.deprecation: Warning when an deprecated class or method is used; 2.unchecked: Warning when an unchecked conversion is performed, for example, when using a collection, generics is not used to specify the type of collection storage; 3.fallthrough: Warning when the Switch block directly leads to the next situation without Break; 4.path: Warning when there is a nonexistent path in the class path, source file path, etc; 5.serial: Warning when a serialVersionUID definition is missing on a serializable class; 6.finally: Warning when any finally clause cannot be completed normally; 7.all: Warning about all of the above.*/ package annotation; import java.util.Arrays; import java.util.List; public class InternalAnnotation { // The method name will be indicated by a strikethrough @Deprecated public void say() { System.out.println("Noting has to say!"); } public void speak() { System.out.println("I have a dream!"); } @SuppressWarnings(value = { "deprecation" }) public void test() { say(); speak(); } @SafeVarargs static void unsafe(List<String>... stringLists) { Object[] array = stringLists; List<Integer> tmpList = Arrays.asList(66); // The semantics are invalid, but there are no warnings at compile time array[0] = tmpList; // ClassCastException occurs at runtime! String s = stringLists[0].get(0); } @FunctionalInterface public interface Runnable { public abstract void run(); } }
4. User defined annotation
4.1 basic grammar
Annotation is similar to class, interface and enumeration in Java, so its declaration syntax is basically the same, but the keywords used are different @ interface. In the underlying implementation, all defined annotations will automatically inherit Java lang.annotation. Annotation interface.
- Annotation declaration
public @interface CustomAnnotation { }
4.2 implementation of annotation type elements
According to our experience in custom classes, the implementation part of a class is nothing more than writing constructs, properties, or methods. However, in a custom annotation, its implementation part can only define one thing: annotation type element.
- Annotation type element
1. The access modifier must be public. If it is not written, it is public by default;
2. The type of this element can only be basic data type, String, Class, enumeration type, annotation type (reflecting the nesting effect of annotations) and a one bit array of the above types;
3. The name of this element is generally defined as a noun. If there is only one element in the annotation, please name it value (it will be convenient to use later);
4. () is not a place to define method parameters, nor can any parameters be defined in parentheses. It is just a special syntax;
5.default represents the default value, which must be consistent with the type defined in point 2;
6. If there is no default value, it means that the element of this type must be assigned a value when the annotation is used later.
public @interface CustomAnnotation { public String name(); int age() default 18; int[] array(); }
4.3 user defined annotation
A basic annotation definition only includes the above two parts: 1. The name of the annotation; 2. The type element that the annotation contains. However, when using the JDK's own annotations, we found that some annotations can only be written on methods (such as @ Override); others can be written on classes (such as @ Deprecated). Of course, there are many detailed definitions. How should these definitions be done? Next, it's about the meta annotation!
// The specified Target @CustomAnnotation is qualified and can only be used on classes, interfaces or methods @Target(value = { ElementType.TYPE, ElementType.METHOD }) // The specified Retention @CustomAnnotation is valid at run time and can be read @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CustomAnnotation { public String name(); int age() default 18; int[] array(); }
4.4 configuration and use of user-defined annotations
First, you need to define an annotation, and a simple Java class for annotation modification.
- The @ Target of the annotation CustomAnnotation defined above is defined as ElementType TYPE, ElementType. Method, then its writing position should be above the method definition or above the class;
- For the annotation type elements defined in CustomAnnotation, and some elements have no default value, we must mark () after the tagName when using it, and fill in all annotation type elements without default value one by one in the form of element name = element value in () (those with default value can also be filled with re assignment), separated by a sign;
- Special grammar
1. If the annotation itself has no annotation type element, you can omit () when using the annotation and write it directly as: @ annotation name, which is equivalent to the standard syntax @ annotation name ()!
2. If the annotation book itself has only one annotation type element and is named value, you can directly use: @ annotation name (annotation value), which is equivalent to: @ annotation name (value = annotation value)
3. If an annotation type element in the annotation is an array type, and only one value needs to be filled in when using the annotation, it can be directly written as @ annotation name (type name = type value), which is equivalent to the standard writing method: @ annotation name (type name = {type value})!
4. If the @ Target of an annotation is defined as element Package, then this annotation is configured in package info In Java, but not directly configured on the package code of a class.
public class AnnotationTest { String name; public static void main(String[] args) { AnnotationTest a = new AnnotationTest(); a.person(); } @CustonAnnotation(name = "Ouseki", array = { 1, 2, 3 }) public void person() { System.out.println(name); } } -------------------------------------------------------------------- [console] null
Running the above program will find that the output result is null. Although the user-defined annotation is configured and assigned, the value is not obtained. Therefore, we need further operation.
4.5 reflection operation get annotation
Only when the retention period of the annotation is in the running stage, that is, when the annotation is decorated with @ Retention(RetentionPolicy.RUNTIME), can the annotation be detected and a series of special operations be performed when the JVM is running.
- Reflection instance
1. If the annotation we want to obtain is configured on the Method, we need to obtain it from the Method object; If it is configured on an attribute, it needs to be obtained from the Field object corresponding to the attribute. If it is configured on a type, it needs to be obtained from the Class object. In short, you can get it from whoever you are!
2. The isannotationpresent (class <? Extends annotation > annotationclass) method is used to judge whether a specified annotation is configured on the element;
3. Getannotation (class < a > annotationclass) method is to obtain the annotation specified on the element. Then call the annotation type element method of the annotation to obtain the value data during configuration;
4. There is also a method getAnnotations() on the reflection object, which can obtain all the annotations configured on the object. It will return us an Annotation array. It should be noted that the type of the array is Annotation, which comes from Java Interface of lang.Annotation package.
Learn more → [Reflection] after reading this article, write on your resume with your backhand: be familiar with Java's Reflection mechanism and ask if you don't agree!
public class AnnotationTest { private String name; public void setName(String name) { this.name = name; } @CustonAnnotation(name = "Ouseki", array = { 1, 2, 3 }) public void person() { System.out.println(name); } public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException, InstantiationException { try { // Gets the Class object of the AnnotationTest Class<?> annotationTestClass = Class.forName("com.ITGodRoad.controller.AnnotationTest"); // Gets the Method object of the AnnotationTest Method annotationTestMethod = annotationTestClass.getMethod("person"); if (annotationTestMethod.isAnnotationPresent(CustonAnnotation.class)) { System.out.println("AnnotationTest Class CustonAnnotation Comments!"); // Gets the annotation of the specified type on the element CustonAnnotation custonAnnotation = annotationTestMethod.getAnnotation(CustonAnnotation.class); System.out.println("name: " + custonAnnotation.name() + ", age: " + custonAnnotation.age() + ", number: " + custonAnnotation.array()[0]); // Instantiate object: newInstance() from jdk1 9 has been discarded because compile time exceptions have been bypassed; The following methods are recommended Object obj = annotationTestClass.getDeclaredConstructor().newInstance(); Method setMethod = annotationTestClass.getMethod("setName", String.class); setMethod.invoke(obj, custonAnnotation.name()); // Execute the person () method to check whether the annotation value has been successfully injected into the class ((AnnotationTest) obj).person(); } else { System.out.println("AnnotationTest No configuration on class CustonAnnotation Comments!"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } -------------------------------------------------------------------- [console] AnnotationTest Class CustonAnnotation Comments! name: Ouseki, age: 18, number: 1 Ouseki
[daily]
The difference and relation between java and javax
java is the API (Application Programming Interface) package of java, and java is the core package. java class library is the basic library determined at the beginning of java release.
javax is also an API (Application Programming Interface) package of Java. javax x means extension, that is, an extension package. javax class library is a layer added to the basic Java library to keep the original version compatible, but some things have better solutions, so we add some, typically awt (Abstract Windowing ToolKit) and swing.
Moving extensions from the javax package to the java package is too cumbersome and will eventually destroy a pile of existing code. So in fact, there is no difference between Java and javax. They are all part of the Java standard API
In fact, it's easy to understand that assigning an object without generics to an object with generics, why not? It's very simple, because if you don't bring generics, the generics will be set as object by default, which means that any type can be plugged in. How can you give a plug with generics if you don't bring generics.
Note: variable parameters are more likely to cause heap pollution exceptions, because java does not allow the creation of generic arrays, and variable parameters are arrays. ↩︎What is a function? If there is only one abstract method in the interface (it can contain multiple default methods or multiple static methods), the interface body can only declare constant fields and abstract methods, which are implicitly declared as public, static and final. There can be no private methods or variables in the interface. ↩︎