1, Annotation
1. Introduction to annotation
concept
Java annotation is a new feature introduced in JDK5. Annotation (also known as metadata) provides a formal method for us to add information to the code, so that we can easily use these data at a later time. Annotation type definition specifies a new type, a special interface type. Add the @ symbol before the keyword interface, that is, use @ interface to distinguish the definition of annotation from the ordinary interface declaration. At present, most frameworks (such as Spring Boot, etc.) simplify the code and improve the coding efficiency by using annotations.
effect
- Provide information to the compiler: the compiler can use annotations to detect errors and warnings, such as @ Override, @ Deprecated.
- Processing in compilation stage: software tools can be used to generate code, Html documents or other corresponding processing by using annotation information, such as @ Param, @ Return, @ See, @ Author to generate Javadoc documents.
- Runtime processing: some annotations can be extracted from the code when the program is running. It is worth noting that annotations are not part of the code itself. For example, Spring 2.5 starts annotation configuration, which reduces the configuration.
2. Built in annotation
- @Override: defined in java,lang.override. This annotation is only applicable to rhetorical methods, indicating that one method declaration intends to override another method declaration in the superclass
- @Deprecated: redefine Java In lang. deprecated, this annotation is used for rhetoric, attributes and classes, indicating that programmers are not encouraged to use such elements, usually because they are dangerous or have better choices.
- @SuppressWarnings: defined in Java Lang. SuppressWarnings is used to suppress the warning message of the compiler. It is different from the first two comments. You need to add a parameter to use it normally. These parameters have been defined. We can use them selectively
- @SuppressWarnings("all")
- @SuppressWarnings("unchecked")
- @SuppressWarnings(value={"unchecked","deprecation"})
Code demonstration
package Annotation; import java.util.ArrayList; import java.util.List; public class Demo01_Annotation extends Object { //@override is an annotation @Override public String toString(){ return super.toString(); } //@Deprecated you recommend programmers to use, but you can use it, or there is a better way to update it @Deprecated public static void test(){ System.out.println("Deprecated"); } //@SuppressWaring suppression warning @SuppressWarnings("all") public void test01(){ List<String> list = new ArrayList<String>(); } public static void main(String[] args) { test(); } }
3. User defined annotation, 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 are in Java Lang, which can be found in the annotation package (@Target,@Retention,@Document.@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 message needs to be saved. It is used to describe the lifecycle of the annotation (source < class < rumtime)
- @Document: note that the annotation will be included in javadoc
- @Inherited: indicates that the subclass can inherit the annotation in the parent class
package Annotation; import java.lang.annotation.*; @MyAnnotation public class Demo02_MetaAnnotation { @MyAnnotation public static void test(){ } public static void main(String[] args) { test(); } } //Define an annotation //@Where can Target be used //ElementType.METHOD method is valid, ElementType Valid on type class @Target(value ={ElementType.METHOD,ElementType.TYPE}) //Where does Retention work //RUNTIME>CLASS>SOURCES @Retention(value = RetentionPolicy.RUNTIME) //@Documented indicates whether our annotations are generated in Javadoc @Documented //@The Inherited subclass can inherit the annotation of the parent class @Inherited @interface MyAnnotation { }
Custom annotation
When using @ interface to customize the annotation, java.com is automatically inherited lang.annotation. Annotation interface
analysis:
- @Interface is used to declare an annotation. Format: public @interface annotation name {definition content}
- 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)
- You can declare the default value of the parameter 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.
package Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class Demo03_CustomAnnotation { //The annotation can display the assignment. If there is no default value, the annotation must be assigned @MyAnnotation2(name = "Zhang San") public void test(){ System.out.println(); } public static void main(String[] args) { new Demo03_CustomAnnotation().test(); } } @Target(value = {ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation2{ //Annotated parameters: parameter type + parameter name () //String name(); String name() default ""; int age() default 0; int id() default -1;//-1 means that does not exist String[] schools() default {"Western open source","Peking University"}; }
2, Reflection mechanism
1.Java reflection mechanism concept
1.1 static & dynamic language
Static VS dynamic language
Dynamic language
- It is a kind of language that can change its structure at run time: for example, new functions, objects and even code can be introduced, existing functions can be deleted or other structural changes. Generally speaking, the code can change its structure according to some conditions at run time
- Main dynamic languages: JavaScript, PHP,Python,C#
Static language
- Corresponding to dynamic language, the language with immutable runtime structure is static language. Such as Java,C,C + +,
- Java is not a dynamic language, but Java may be called "quasi dynamic language". That is, Java has certain dynamics, and we can use reflection mechanism to obtain characteristics similar to dynamic language. Java's dynamics makes programming more flexible!
1.2 concept of reflection mechanism
Java Reflection
- Reflection is the key to Java being regarded as a dynamic language. The reflection mechanism allows the program 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
Class c = Class.forName("java.lang.string")
After loading the Class, an object of Class type is generated in the method area of heap memory (a Class has only one Class object), which contains the complete structure information of the Class. We can see the structure of the Class through this object. This object is like a mirror, through which we can see the structure of the Class. We can 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
package Annotation; public class Test2 { public static void main(String[] args) throws ClassNotFoundException { //Get the Class of the Class through reflection //--->View JDK help documentation Class c1 = Class.forName("Annotation.User"); System.out.println(c1); Class c2 = Class.forName("Annotation.User"); System.out.println(c1.hashCode()); System.out.println(c2.hashCode()); } } // package Annotation; public class User { private int id; private int age; private String 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; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
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 runtime
- Call the member variables and methods of any object at run time
- Processing annotations at run time
- Generate dynamic proxy
- ...
Advantages and disadvantages of Java reflection
Advantages: it can dynamically create objects and compile, reflecting great flexibility!
Lack of determination: it has an impact on performance. Using reflection is basically an interpretive operation. We can tell the JVM what we want to do and it meets our requirements.
Such operations are always slower than performing the same operation directly.
1.3 main API s related to reflection
- Java.lang.Class: represents a class
- Java.lang.reflect.Method: represents the method of the class
- Java.lang.reflect.Field: represents the member variable of the class
- Java.lang.reflect.Constructor: represents the constructor of the class
- ...
2.Class
The following methods are defined in the Object class, which will be inherited by all subclasses
public final Class getClass();
The type of the return value of the above method is a Class class. This Class is the source of Java distribution, which actually reflects the running results of the program
There are also many understandings, that is, the name of the class can be obtained through object reflection.
The information that can be obtained after the object looks in the mirror: the properties, methods and constructors of a Class, and which interfaces a Class implements. For each Class, the JRE keeps an object of the same Class type for it. A Class object contains information about a specific structure (class/interface/enum/annotation/primitive type/void / []).
- Class itself is also a class
- Class objects can only be created by the system
- A loaded Class will only have one Class instance in the JVM
- A class object corresponds to one loaded into the JVM Class file
- 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
2.1 common methods of class
2.2 get the instance of Class
package Annotation; public class Demo05_CreateClass { public static void main(String[] args) throws ClassNotFoundException { User user = new User(); //Method 1: query by object Class c1 = user.getClass(); System.out.println(c1.hashCode()); //Method 2: forName Class c2 = Class.forName("Annotation.User"); System.out.println(c2.hashCode()); //Method 3: pass the class name Class get Class c3 = User.class; System.out.println(c3.hashCode()); } }
package Annotation; import java.lang.annotation.ElementType; public class Demo06_AllTypeClass { public static void main(String[] args) { Class c1 = Object.class;//class Class c2 = Comparable.class;//Interface Class c3 = String[].class;//String array Class c4 = int[].class;//One dimensional array Class c5 = int[][].class;//Two dimensional array Class c6 = Override.class;//annotation Class c7 = ElementType.class;//enumeration Class c8 = Integer.class;//Basic data type Class c9 = void.class;//void Class c10 = Class.class;//class System.out.println(c1); System.out.println(c2); System.out.println(c3); System.out.println(c4); System.out.println(c5); System.out.println(c6); System.out.println(c7); System.out.println(c8); System.out.println(c9); System.out.println(c10); //As long as the element type is consistent with the dimension, it is the same Class System.out.println("//"); int[] a = new int[10]; int[] b = new int[10]; System.out.println(a.getClass().hashCode()); System.out.println(b.getClass().hashCode()); } }
3. Class loading and ClassLoader
3.1 JAVA memory analysis
Loading of class 3.2
//Class loading public class Demo05_ClassLoader { public static void main(String[] args) { A a = new A(); System.out.println(A.m); /** * 1. When loaded into memory, a Class object corresponding to the Class will be generated * 2. Link, m=0 after connection * 3. initialization * <clinit>(){ * System.out.println("A Class static code block initialization ""); * m = 300; * m = 100; * } */ } } class A { static { System.out.println("A Class static code block initialization"); m = 300; } static int m = 100; public A() { System.out.println("A Class parameterless construction initialization"); } }
Analyze the above code
The program is executed from top to bottom
//When will the test class initialize public class Demo08_ActiveReference { static { System.out.println("Main Class is loaded"); } public static void main(String[] args) throws ClassNotFoundException { // 1. Active call //Son son = new Son(); // Reflection also produces active references //Class.forName("cn.doris.reflection.Son"); //A method that does not generate a reference to a class //System.out.println(Son.b); //Son[] array = new Son[5]; //System.out.println(Son.a); } } class Father { static final int b = 2; static { System.out.println("Parent class loaded"); } } class Son extends Father { static { System.out.println("Subclass loaded"); m = 100; } static int m = 300; static final int a = 1; }
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();//Gets the loader of the system class ClassLoader parent = systemClassLoader.getParent();//Get the parent class loader of the system class loader – > extended class loader jre1 8.0_ 91\lib\ext ClassLoader parent1 = parent.getParent();//Get extension class loader parent class loader – > root loader (C / C + +) jre1 8.0_ 91\lib\rt.jar
//Class loader public class Demo09_ClassLoader1 { 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 of the system class loader -- > extension class loader jre1 8.0_ 91\lib\ext ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); //Get extension class loader, parent class loader -- > root loader (C / C + +) jre1 8.0_ 91\lib\rt.jar ClassLoader parent1 = parent.getParent(); System.out.println(parent1); //Test which loader loads the current class ClassLoader classLoader = Class.forName("cn.doris.reflection.Demo09_ClassLoader1").getClassLoader(); System.out.println(classLoader); //Test who loaded the built-in classes in JDK classLoader = Class.forName("java.lang.Object").getClassLoader(); System.out.println(classLoader); //How to get the path that the system class loader can load System.out.println(System.getProperty("java.class.path")); //The parental delegation mechanism detects the security of the classes you write and the classes that will not use you like the loader //java. Lang.string -- > push up /** * D:\Environment\java\jdk1.8.0_91\jre\lib\charsets.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\deploy.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\access-bridge-64.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\cldrdata.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\dnsns.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\jaccess.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\jfxrt.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\localedata.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\nashorn.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\sunec.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\sunjce_provider.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\sunmscapi.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\sunpkcs11.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\ext\zipfs.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\javaws.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\jce.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\jfr.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\jfxswt.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\jsse.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\management-agent.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\plugin.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\resources.jar; * D:\Environment\java\jdk1.8.0_91\jre\lib\rt.jar; * E:\StudyProject\annotation_reflection\out\production\annotation_reflection; * D:\WorkingSoftware\IntelliJ IDEA 2020.3.1\lib\idea_rt.jar */ } }
4. Create the object of the runtime class
5. Get the complete structure of the running class*
Classc1=Class.forName(“cn.doris.reflection.User”); // Gets the class of the current object
//Get the name of the class
c1.getName();// Get package name + class name
c1.getSimpleName();// Get class name
//Get the properties of the class
c1.getFields();// Only public properties can be found
c1.getDeclaredFields();// Find all properties
c1.getDeclaredField(“name”); // Gets the value of the specified property
//Method to get class
c1.getMethods(); // Get all public methods of this class and its parent class
c1.getDeclaredMethods(); // Get all methods of this class
c1.getMethod(“getName”, null);// Gets the specified method
//Gets the constructor of the class
c1.getConstructors();
c1.getDeclaredConstructors();
c1.getDeclaredConstructor(String.class, int.class, int.class);// Gets the specified constructor
6. Call the specified structure of the runtime class
6.1 what can I do with Class objects
6.2 method and use
//Get Class object
Class c1 = Class.forName("cn.doris.reflection.User");
//Essentially calls the class's parameterless constructor
User user = (User) c1.newInstance();
//Constructor to create objects
Constructor constructor=c1.getDeclaredConstructor(String.class, int.class, int.class);
User user1 = (User) constructor.newInstance("long song", 001,17);
//invoke: Activate
//(object, "method value")
setName.invoke(user2, "doris");
//Set security detection
name.setAccessible(true);
//Dynamically create objects through reflection public class Demo11_DynamicCreateObject { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //Get Class object Class c1 = Class.forName("cn.doris.reflection.User"); //Construct an object /*User user = (User) c1.newInstance();//Essentially calls the class's parameterless constructor System.out.println(user);*/ //Creating objects through constructors /*Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class); User user1 = (User) constructor.newInstance("Long song ", 001,17); System.out.println(user1);*/ //Call normal methods through reflection User user2 = (User) c1.newInstance(); //Get a method by reflection Method setName = c1.getDeclaredMethod("setName", String.class); //invoke: Activate // (object, "method value") setName.invoke(user2, "doris"); System.out.println(user2.getName()); //Operation properties by reflection User user3 = (User) c1.newInstance(); Field name = c1.getDeclaredField("name"); //Private properties cannot be operated directly. We need to turn off the security detection of the program and setAccessible(true) of the property or method //Set security detection name.setAccessible(true); name.set(user3, "doris2"); System.out.println(user3.getName()); } }
7. Reflection operation generics
8. Reflection operation notes
//Practice reflection operation annotation public class Demo14_ORM { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("cn.doris.reflection.Student2"); //Get annotations through reflection Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } //Get annotation value TableDoris tableDoris = (TableDoris) c1.getAnnotation(TableDoris.class); String value = tableDoris.value(); System.out.println(value); //Gets the annotation specified by the class Field name = c1.getDeclaredField("name"); FiledDoris annotation = name.getAnnotation(FiledDoris.class); System.out.println(annotation.columnName()); System.out.println(annotation.type()); System.out.println(annotation.length()); } } @TableDoris("db_student") class Student2 { @FiledDoris(columnName = "db_id", type = "int", length = 10) private int id; @FiledDoris(columnName = "db_age", type = "int", length = 3) private int age; @FiledDoris(columnName = "db_name", type = "varchar", length = 200) private String name; public Student2() { } public Student2(int id, int age, String name) { this.id = id; this.age = age; this.name = name; } @Override public String toString() { return "Student2{" + "id=" + id + ", age=" + age + ", 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; } public String getName() { return name; } public void setName(String name) { this.name = name; } } //Class name annotation @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface TableDoris { String value(); } //Attribute annotation @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface FiledDoris { String columnName(); String type(); int length(); }