Annotation and reflection - Annotation
What is annotation
- Explain a meaning to a computer
- Can be read by other programs
//What is annotation? public class dom1 extends Object{ //Rewrite annotation @Override public String toString() { return super.toString(); } }
- Format: @ comment name, and some parameter values can be added, such as @ comment name (value = "parameter")
- Additional supporting information
- Check and constraints
Built in annotation
- @Override: override method
- @Deprecated: not recommended, but can be used
- @SuppressWarnings: suppress warnings. Parameters need to be added
import java.awt.*; import java.security.AllPermission; //What is annotation? public class dom1 extends Object{ //Rewrite annotation @Override public String toString() { return super.toString(); } @Deprecated public static void text(){ System.out.println("666"); } @SuppressWarnings("all") public void test(){ int xx; List list = new List(); } public static void main(String[] args) { text(); } }
Meta annotation
- Responsible for annotating other annotations, which is also gradual
-
- @Target: describes the scope of application of the annotation
- @Retention: describes the lifecycle of annotations: runtime > class > source
- @Document: generate annotation in Doc
- @Inherited: the subclass can inherit the annotation in the parent class
import java.lang.annotation.*; //Test notes public class dom02 { @MyAnnotation public void test(){} } //Define an annotation @Target(value = ElementType.METHOD) @Retention(value = RetentionPolicy.RUNTIME) @Documented @Inherited @interface MyAnnotation{}
Custom annotation
- Automatically inherit the Annotation interface
import java.lang.annotation.ElementType; import java.lang.annotation.Target; //Custom annotation public class dom3 { //Annotations can be assigned explicitly. If there is no default value, they must be assigned @Test(name = "aaa") public void test(){} @Test2("00")//Only one parameter is value, which can be omitted public void test2(){} } @Target({ElementType.METHOD}) @interface Test{ //Annotated parameter: parameter type + parameter name () default value String name() default ""; int age() default 18; int id() default -1; //The default value is - 1, which means it does not exist String[] come() default {"010101","333"}; } @Target({ElementType.METHOD}) @interface Test2{ String value(); }
Reflection overview
-
Reflection mechanism: Reflection
-
Dynamic language: a language whose structure can be changed at run time
-
Static language: cannot be changed!
-
java is a static language, but reflection mechanism can give it the characteristics of dynamic language - "quasi dynamic language";
-
Reflection: seeing the structure of a class through a mirror
Normal method: import package class name - new instantiation - instantiate object
Reflection method: instantiate object - "getClass() method" - get package class name
function f(){ var x = "var a = 3 ; var b = s; alert(a+b)"; eval(x); }
Get reflection object
- Dynamic object creation and compilation, flexibility
- Performance impact, slower than direct operations
//What is reflection public class dom4 extends Object{ public static void main(String[] args) throws ClassNotFoundException { //Get class object through reflection Class c1 = Class.forName("study1.User"); System.out.println(c1); //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 c2 = Class.forName("study1.User"); Class c3 = Class.forName("study1.User"); Class c4 = Class.forName("study1.User"); System.out.println(c2.hashCode()); System.out.println(c3.hashCode()); System.out.println(c4.hashCode()); } } //Entity class class User{ private String name; private int id; public User(){ } public User(String name,int id){ this.name = name; this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", id=" + id + '}'; } }
Several methods to get class
//Test the methods of creating class class public class dom5 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println(person.name); //Obtained by object Class c1 = person.getClass(); System.out.println(c1.hashCode()); //forname get Class c2 = Class.forName("study1.Student"); System.out.println(c2.hashCode()); //class name. class Class c3 = Student.class; System.out.println(c3.hashCode()); //Wrapper classes with basic built-in properties have Type properties Class c4 = Integer.TYPE; System.out.println(c4.hashCode()); //Get parent type Class c5 = c1.getSuperclass(); System.out.println(c5); } } class Person{ public String name; public Person() { } public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person{ public Student(String name){ this.name = "student"; } } class Teacher extends Person{ public Teacher(){ this.name = "teacher"; } }
class objects of all types
package study1; import java.lang.annotation.ElementType; //All types of class es public class dom6 { public static void main(String[] args) { Class c1 = Object.class; //class Class c2 = Comparable.class; //Interface Class c3 = String[].class; // array Class c4 = int[][].class; //Two dimensional array Class c5 = Override.class; // annotation Class c6 = ElementType.class; // enumeration Class c7 = Integer.class; //Basic data type Class c8 = void.class; //void Class c9 = 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); //The element type is the same as the dimension, which is the same class int[] a = new int[10]; int[] b = new int[100]; System.out.println(a.getClass().hashCode()); System.out.println(b.getClass().hashCode()); } }
Class load memory analysis
- Core idea: java Memory understanding: heap, stack, constant pool, method area
package study1; public class dom7 { public static void main(String[] args) { A a = new A(); System.out.println(A.a); /** *1.Load the class class into memory and generate a java. long. Class object * 2.Link: it will verify whether the class information complies with the JVM virtual machine specification, security issues, formally allocate memory (heap area) for class variables and set the initial value of class variables * 3.Initialization: execute the < client > () method of the class constructor. When new, the class object in the heap returns to the method area to automatically collect the assignment action of variables and the data in the static code block * Statement and merge the code. The class constructor constructs all the information of the class, not the class object. The JVM ensures that the < client > () method of a class is locked and synchronized correctly in multithreading. * * */ } } class A{ static { System.out.println("A Class static code block initialization"); a = 300; } static int a = 100; public A (){ System.out.println("A Class parameterless construction initialization"); } }
Initialization of analysis class
//When will the test initialize public class dom8 { static { System.out.println("Main Method is loaded"); } public static void main(String[] args) throws ClassNotFoundException { //Active reference //Son son = new Son(); //Reflection produces an active reference //Class.forName("study1.Son"); //Class initialization will not occur //Calling a parent method through a subclass does not initialize the subclass //System.out.println(Son.b); //Array definition class reference //Son[] array = new Son[1]; //Reference constant //System.out.println(Son.A); } } class Father{ static int b = 2; static { System.out.println("The parent class is loaded"); } } class Son extends Father{ static { System.out.println("Subclass loaded"); a = 300; } static int a = 100; static final int A = 1;//static const }
Class loader
public class dom9 { public static void main(String[] args) throws ClassNotFoundException { //Bottom up check if loaded //Get system class loader -- sun.misc.Launcher$AppClassLoader@xxx ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); //Get the parent class loader of the class loader - > extended class loader -- - sun.misc.Launcher$ExtClassLoader@ ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); //Get the parent class of the extension class loader -- > boot loader (written in core! C + +, which the user cannot get directly) -- null ClassLoader parent1 = parent.getParent(); System.out.println(parent1); //Test which loader the current class is ClassLoader classLoader = Class.forName("study1.dom9").getClassLoader(); System.out.println(classLoader); //Test who loads the Jdk inner class 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")); //Parent delegation mechanism -- multiple detection to detect package security and avoid duplicate package names } }
Get class runtime structure
- Attribute: Field
- Method: method
- Constructor: constructor
- Interface: Interface
- Annotation: Annotation
- Superclass: inherited parent class
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; //Get class information public class dom10 { public static void main(String[] args) throws ClassNotFoundException { Class c1 = Class.forName("study1.Son"); System.out.println(c1.getName()); //Get package name and class name System.out.println(c1.getSimpleName()); //Get class name //Get the properties of the class Field[] fields = c1.getFields();//public property fields = c1.getDeclaredFields();//All properties for (Field field : fields) { System.out.println(field); } //Method to get class for (Method method : c1.getMethods()) { System.out.println(method); } //Gets the constructor of the class for (Constructor constructor : c1.getConstructors()) { System.out.println(constructor); } for (Constructor declaredConstructor : c1.getDeclaredConstructors()) { System.out.println(declaredConstructor); } } }
Dynamically create object execution methods
- Call the newInstance method of the Class object
- setAccessible: security check, skip permission detection: method,Field,Constructor
import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class dom11 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class c1 = Class.forName("study1.Son"); Son o = (Son) c1.newInstance(); System.out.println(o); //Create an object through a constructor -- call a parameterized constructor Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,""); Son o1 = (Son) declaredConstructor.newInstance(""); //Call normal methods through reflection Son o2 = (Son) c1.newInstance(); Method declaredMethod = c1.getDeclaredMethod("",String.class); //Activation method declaredConstructor.invoke("object","Method value"); //By reflecting the operation attributes, you cannot directly operate the attributes. You need to close the security check Son o3 = (Son)c1.newInstance(); } }
Performance comparison and analysis
- Test results:
Common method: 32ms
Reflection method: 20677ms
Closing inspection: 779ms
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; //Analyze performance and execute 100 million times public class dom12 { //Common method public static void test1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); long startTime = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { user.getName(); } long endTime = System.currentTimeMillis(); System.out.println("Common method:" +(endTime-startTime)+"ms"); } //Reflection call public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); long startTime = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { //Activation method: object name, parameter getName.invoke(user,null); } long endTime = System.currentTimeMillis(); System.out.println("Reflection method:" +(endTime-startTime)+"ms"); } //Close check public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); //Close safety check getName.setAccessible(true); long startTime = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { //Activation method: object name, parameter getName.invoke(user,null); } long endTime = System.currentTimeMillis(); System.out.println("Close check:" +(endTime-startTime)+"ms"); } public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { test1(); test2(); test3(); } }
Get generic information*
//Get generic information through reflection public class dom13 { public void test(Map<String,User>map, List<User>list){ System.out.println("test"); } public Map<String,User> test2 (){ System.out.println("test2"); return null; } public static void main(String[] args) throws NoSuchMethodException { Method test = dom13.class.getMethod("test", Map.class, List.class); for (Type genericParameterType : test.getGenericParameterTypes()) { System.out.println(genericParameterType); if(genericParameterType instanceof ParameterizedType){ for (Type actualTypeArgument : ((ParameterizedType) genericParameterType).getActualTypeArguments()) { System.out.println(actualTypeArgument); } } } } }
Get annotation information
- ORM - > Object Relational Mapping
import java.lang.annotation.*; import java.lang.reflect.AnnotatedType; public class dom14 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("study1.Student2"); //Get annotations through reflection for (Annotation annotation : c1.getAnnotations()) { System.out.println(annotation); } //Get annotated value Table annotation = (Table)c1.getAnnotation(Table.class); String value = annotation.value(); System.out.println(value); //Gets the annotation specified by the class Field f = c1.getDeclaredField("name"); Field annotation1 = f.getAnnotation(Field.class); System.out.println(annotation1.col()); System.out.println(annotation1.length()); System.out.println(annotation1.type()); } } @Table("student") class Student2{ @Field(col = "id",type = "int",length = 10) private int id; @Field(col = "age",type = "int",length = 10) private int age; @Field(col = "name",type = "varchar",length = 5) private String name; public Student2() { } public Student2(int id ,int age,String name){ this.age = age; this.id = id; this.name = name; } public Student2(int age) { this.age = age; } 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; } @Override public String toString() { return "Student2{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + '}'; } } //Annotation of class name @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Table{ String value(); } //Attribute annotation @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface Field{ String col(); String type(); int length(); }