Annotation and reflection
1, What is annotation
-
Annotation is a new technology introduced from JDK 5.0
-
Function of Annotation:
-
Not the program itself, you can explain the program
-
It can be read by other programs (such as compiler, etc.)
-
-
Format of Annotation:
Comments exist in the code as @ comment name. You can also add some parameter values, such as @ SuppressWarnings(value = "unchecked") -
Where is Annotation used?
- It can be attached to package, class, method, field, etc., which is equivalent to adding additional auxiliary information to them. We can access these metadata through reflection mechanism programming
public class Test01 extends Object { //@Override overridden annotation @Override public String toString() { return super.toString(); } }
2, Built in annotation
Three common built-in annotations
- @Override: defined in java.lang.Override. This annotation is only applicable to rhetoric. It indicates that one method declaration intends to override another method declaration in the superclass
- @Deprecated: defined in java.lang.Deprecated. This annotation can be used for rhetoric, attributes, and classes to indicate that programmers are not encouraged to use such elements, usually because it is dangerous or there is a better choice
- suppressWarnings: defined in java.lang.SuppressWarnings to suppress warnings at compile time
- Different from the previous two comments, you need to add a parameter to use it correctly. These parameters have been defined. We can use them selectively
@SuppressWarnings("all")
@SuppressWarnings("unchecked")
@SuppressWarnings(value = {"unchecked", "depreciation"}) and so on
- Different from the previous two comments, you need to add a parameter to use it correctly. These parameters have been defined. We can use them selectively
3, Meta annotation
- The function of meta annotation is to annotate other annotations. Java 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. (@ target, @ retention, @ documented, @ inherited)
- @Target: used to describe the scope of use of annotations (i.e. where the described annotations can be used)
- @Retention: indicates the level at which the annotation information needs to be saved. It is used to describe the annotation life cycle (source < class < runtime)
- @Document: note that the annotation will be included in javadoc
- @Lninherited: indicates that the subclass can inherit the annotation in the parent class
import java.lang.annotation.*; public class Test02 { public void test(){ } } //Custom annotation //Target indicates where annotations can be used @Target(value = ) //@Retention indicates where our annotation is still valid @Retention(value = RetentionPolicy.RUNTIME) //@Documented indicates whether annotations are generated in JAVAdoc @Documented //@The Inherited subclass can inherit the annotation of the parent class @Inherited @interface MyAnnotation{ }
4, Custom annotation
When using @ interface to customize annotations, it automatically inherits the java.lang.annotation.Annotation interface
analysis
- Interface is used to declare an annotation. Format: public @interface annotation name
- Each of these methods actually declares a configuration parameter
- The name of the method is the name of the parameter
- The return value type is the type of the parameter (the return value can only be the basic type, class, string, enum). The default value of the parameter can be declared through default
- If there is only one parameter member, the general parameter name is value
- An annotation element must have a value. When defining an annotation element, we often use an empty string with 0 as the default value
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class Test03 { //Annotations can display assignments. If there is no default value, the annotation must be assigned @MyAnnotation2(name="JF") public void test2(){} @MyAnnotation3("JF") public void test3(){} } @Target() @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation2{ //Annotated parameters: parameter type + parameter name String name() default ""; //The default value is empty int age() default 0; int id() default -1;//If it cannot be found, it returns - 1, indicating that it does not exist String[] schools() default {"Guangli"}; } @Target() @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation3{ String value(); // When there is only one value, it is recommended to name it with value }
5, Reflection overview
-
Reflection is the key to Java being regarded as a dynamic language. Reflection mechanism allows programs to obtain the internal information of any class with the help of Reflection API during execution, and can directly operate the internal properties and methods of any object.
-
After loading the Class, an object of Class type (a Class has only one Class object) is generated in the method area of the heap memory. This object contains the complete Class structure information. We can see the Class structure through this object. This object is like a mirror. We can see the Class structure through this mirror. Therefore, we vividly call it reflection
Normal method: import the required "package class" name - > instantiate through new - > obtain the instantiated object
Reflection method: instantiate object - > getClass () method - > get the complete "package class" name
6, Get reflection object
Functions provided by Java reflection mechanism
- Determine the class of any object at run time
- Construct an object of any class at run time
- Judge the member variables and methods of any class at run time
- Get generic information at run time
- Call the member variables and methods of any object at run time
- Processing annotations at run time
- Generate dynamic proxy
Main API s related to reflection
- java.lang.Class: represents a class
- ava.lang.reflect.Method: method representing a class
- java.lang.reflect.Field: represents the member variable of the class
- java.lang.reflect.Constructor: constructor representing a class
package com.jf.reflection; /** * @Author : JF * @CreatTime : 2021/9/20 11:30 * @Description: */ public class Test01 { public static void main(String[] args) throws ClassNotFoundException { //Get the class object of the class through reflection //A class has only one class object in memory //After a class is loaded, the whole structure of the class will be encapsulated in the class object. Class c1 = Class.forName("com.jf.reflection.User"); System.out.println(c1); System.out.println(c1.hashCode()); } } //Entity class class User { private String name; private int id; private int age; public User() { } public User(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Test01{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}'; } }
7, Several ways to get class
- Class itself is also a class
- Class objects can only be created by the system
- A loaded Class has only one Class instance in the JVM
- A class object corresponds to a class file loaded into the JVM
- Each Class instance will remember which Class instance it was generated from
- All loaded structures in a Class can be completely obtained through Class
- Class is the root of Reflection. For any class you want to dynamically load and run, you have to obtain the corresponding class object first
Common methods of class
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-vmr1cym8-1632720110280) (annotation and reflection. assets/image-20210920115122132.png)]
8, Analysis class initialization
- Active reference of class (class initialization must occur)
- When the virtual machine starts, initialize the class where the main method is located first
- new is an object of a class
- Call static members (except final constants) and static methods of the class
- Use the methods of the java.lang.reflect package to make reflection calls to the class
- When initializing a class, if its parent class is not initialized, its parent class will be initialized first
- Passive reference of class (class initialization will not occur)
- When accessing a static domain, only the class that actually declares the domain will be initialized. For example, when the static variable of the parent class is referenced through the subclass, the subclass will not be initialized
- Defining a class reference through an array does not trigger the initialization of this class
- Reference constants do not trigger the initialization of this class (constants are stored in the constant pool of the calling class in the link phase)
9, Class loader
- The function of class loading: load the bytecode content of the class file into memory, convert these static data into the runtime data structure of the method area, and then generate a java.lang.Class object representing this class in the heap as the access entry to the class data in the method area.
- Class caching: the standard JavaSE class loader can find classes as required, but once a class is loaded into the class loader, it will remain loaded (cached) for a period of time. However, the JVM garbage collection mechanism can recycle these class objects
public class Test03 { public static void main(String[] args) throws ClassNotFoundException { //Gets the loader of the system class ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); //Get the parent class loader - > extension class loader of the system class loader ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); //Gets the parent class loader - > root loader of the extension class loader ClassLoader parent1 = parent.getParent(); System.out.println(parent1); //Test which loader the current class is ClassLoader classLoader = Class.forName("com.jf.reflection.Test03").getClassLoader(); System.out.println(classLoader); } }