annotation
-
Function of annotation:
(1) It is not the procedure itself, which can be explained
(2) It can be read by other programs (such as compiler, etc.)
-
Format of Annotation:
Annotations exist in the code as "@ annotation 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
Built in annotation
-
@Override
Defined in java.lang.Override, this annotation is only applicable to rhetoric, indicating 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
It is defined in java.lang.suppresswarnings to suppress warnings at compile time.
Different from the first two comments, you need to add a parameter to use it correctly. These parameters have been defined. Optional use.
@SupressWarnings("all")
@SupressWarnings("unchecked")
@Suppress warnings (value = {"unchecked", "depreciation"}) and so on
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)
(1)@Target: used to describe the scope of use of annotations (where the described annotations can be used)
(2)@Retention: indicates the level at which the annotation information needs to be saved, which is used to describe the annotation life cycle
(SOURCE < CLASS < RUNTIME)
(3)@Document: note that the annotation will be included in javadoc
(4)@Inherited: indicates that the subclass can inherit the annotation in the parent class
import java.lang.annotation.*; //Test meta annotation @MyAnnotation public class Test02 { public void test(){ } } //Define an annotation //Target indicates where our annotation can be used. The first value indicates that it can be used on methods and the second value indicates that it can be used on classes @Target(value = {ElementType.METHOD, ElementType.TYPE}) //Retention indicates where our comments are still valid //runtime>class>sources @Retention(value = RetentionPolicy.RUNTIME) //Documented indicates whether our annotations are generated in JAVAdoc @Documented //A subclass can inherit the annotation of the parent class @Inherited @interface MyAnnotation{ //Define the annotation and modify it with public @interface }
Custom annotation
-
When using @ interface to customize annotations, it automatically inherits the java.lang.annotation.Annotation interface
-
analysis:
(1)@interface is used to declare an annotation. Format: public @interface annotation name {definition content}
(2) Each of these methods actually declares a configuration parameter
(3) The name of the method is the name of the parameter
(4) The return value type is the type of the parameter (the return value can only be the basic type, Class, String, enum)
(5) You can declare the default value of the parameter through default
(6) If there is only one parameter member, the general parameter name is value
(7) 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.*; //Custom annotation public class Test03 { //Annotations can display assignments. If there is no default value, we must assign a value to the annotation @MyAnnotation2(name = "Brandon") public void test(){ } } @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation2{ //Annotated parameters: parameter type + parameter name (); //Default is followed by the default value String name() default ""; int age() default 0; int id() default -1;// If the default value is - 1, it means that it does not exist }
reflex
Reflection overview
Static VS dynamic language
Dynamic language
(1) 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.
(2) Main dynamic languages: Object-C, c#, JavaScript, PHP, Python, etc
Static language
(1) Corresponding to dynamic language, the language with immutable runtime structure is static language. Such as Java, C, C + +.
(2)Java is not a dynamic language, but Java can be called a "quasi dynamic language". That is, Java has certain dynamics. We can use reflection mechanism to obtain characteristics similar to dynamic language. The dynamic nature of Java makes programming more flexible.
//JavaScript function f(){ var x = "var a=3;var b=5;alert(a+b)"; //alert means pop-up window eval(x); //Parse the corresponding string into js code and run it }
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 the Reflection API during execution, and can directly operate the internal properties and methods of any object (you can obtain things decorated with private)
Class c = Class.forName("java.lang.String")
-
After loading the Class, a Class object is generated in the method area of heap memory (a Class has only one Class object), which contains the complete Class structure information. 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. Therefore, we vividly call it reflection
Normal method: import the required "package class" name ---- > instantiate through new ---- > to obtain the instantiated object
Reflection method: instantiate the object - > getClass () method - > get the complete "package class" name
Research and application of Java reflection mechanism
-
Functions provided by Java reflection mechanism
(1) Determine the class of any object at run time
(2) Construct an object of any class at run time
(3) Judge the member variables and methods of any class at run time
(4) Get generic information at run time
(5) Call the member variables and methods of any object at run time
(6) Process comments at run time
(7) Generate dynamic proxy
(8)......
-
Advantages and disadvantages of Java reflection
(1) Advantages:
It can dynamically create objects and compile, reflecting great flexibility.
(2) Disadvantages:
It has an impact on performance. Using reflection is basically an interpretation 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.
-
Main API s related to reflection
(1) java.lang.Class: represents a class
(2) java.lang.reflect.Method: method representing a class
(3) java.lang.reflect.Field: represents the member variable of the class
(4) java.lang.reflect.Constructor: constructor representing a class
(5)......
Class class
The following methods are defined in the Object class, which will be inherited by all subclasses
public final Class getClass()
The return value of the above method is a Class class, which is the source of Java reflection. In fact, the so-called reflection is also well understood from the running results of the program, that is, the name of the Class can be obtained through object reflection.
package reflection; //What is reflection public class Test02 { public static void main(String[] args) throws ClassNotFoundException { //Gets 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("reflection.User");//Under the reflection package System.out.println(c1); //Output class reflection.User c1.get....();//Get the information in the class } } //Entity class: there are only attributes in it. pojo,entity class User{ private String name; private int id; private int age; //Construction method shortcut key alt+insert //Select multiple shift + click the last option 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 "User{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}'; } }
-
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 reserves an invariant Class object for it. A Class object contains information about a specific structure (class/interface/enum/annotation/primitive type/void / []).
(1) Class itself is also a class
(2) Class objects can only be created by the system
(3) A loaded Class has only one Class instance in the JVM
(4) A class object corresponds to a class file loaded into the JVM
(5) Each Class instance will remember which Class instance it was generated from
(6) All loaded structures in a Class can be completely obtained through Class
(7) 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
Method name | Function description |
---|---|
static ClassforName(String name) | Returns the Class object with the specified Class name |
Object newInstance() | Call the default constructor to return an instance of the Class object (create a reflective object) |
getName() | Returns the name of the entity (Class, interface, array or void) represented by this Class object. (get the name of the Class) |
Class getSuperClass() | Returns the Class object of the parent Class of the current Class object |
Class[] getinterfaces() | Gets the interface of the current Class object |
ClassLoader getClassLoader() | Returns the class loader for this class |
Constructor[] getConstructors() | Returns an array containing some Constructor objects |
Method getMothed(String name,Class.. T) | Returns a Method object whose formal parameter type is paramType |
Field[] getDeclaredFields() | Returns an array of Field objects |
Get an instance of Class
1. If a specific class is known, it is obtained through the class attribute of the class. This method is the most safe and reliable and has the highest program performance.
Class clazz = Person.class;
2. If the instance of a Class is known, call the getClass() method of the instance to obtain the Class object.
Class clazz = person.getClass();
3. If the full Class name of a Class is known and the Class is in the Class path, it can be obtained through the static method forName() of Class class, and ClassNotFoundException may be thrown
Class clazz = Class.forName("demo01.Student");
4. The built-in basic data type can directly use the class name. Type
5. You can also use ClassLoader to explain later
-
The code is implemented as follows:
package reflection; //What are the creation methods of the test class public class Test03 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println("This man is" + person.name); //Method 1: obtained by object Class c1 = person.getClass(); System.out.println(c1.hashCode());//Compared with the following, they are the same //Method 2: obtain forName and throw an exception Class c2 = Class.forName("reflection.Student"); System.out.println(c2.hashCode()); //Method 3: obtained by class name. Class Class c3 = Student.class; System.out.println(c3.hashCode()); //Method 4: wrapper classes of basic built-in types have a Type attribute Class c4 = Integer.TYPE; //class of Integer System.out.println(c4); //Output int //Get parent type Class c5 = c1.getSuperclass(); System.out.println(c5); //Output class reflection.Person } } class Person{ public String name; public Person() { } public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person{ public Student() { this.name = "student"; } } class Teacher extends Person{ public Teacher() { this.name = "teacher"; } }
What types can have Class objects?
1.class: external class, member (member internal class, static internal class), local internal class, anonymous internal class
2.interface: Interface
3. []: array
4.enum: Enumeration
5.annotation: annotation @ interface
6.primitive type: basic data type
7.void
import java.lang.annotation.ElementType; //Class of all types public class Test04 { public static void main(String[] args) { Class c1 = Object.class; //Class of class Class c2 = Comparable.class; //Class of interface Class c3 = String[].class; //One dimensional array Class c4 = int[][].class; //Two dimensional array Class c5 = Override.class; //annotation Class c6 = ElementType.class; //Enumeration type Class c7 = Integer.class; //Basic data type Class c8 = void.class; //void Class c9 = Class.class; //Class is also a class //alt plus mouse selection, you can copy and paste vertically System.out.println(c1); //class java.lang.Object System.out.println(c2); //interface java.lang.Comparable System.out.println(c3); //class [Ljava.lang.String; System.out.println(c4); //class [[I System.out.println(c5); //interface java.lang.Override System.out.println(c6); //class java.lang.annotation.ElementType System.out.println(c7); //class java.lang.Integer System.out.println(c8); //void System.out.println(c9); //class java.lang.Class //A Class has only one Class object //As long as the element type is the same as the dimension (one-dimensional, two-dimensional, etc.), it is the same Class int[] a = new int[10]; int[] b = new int[100]; System.out.println(a.getClass().hashCode());//1956725890 System.out.println(b.getClass().hashCode());//1956725890 } }
Class load memory analysis
Java Memory Analysis
heap | new objects and arrays | |
It can be shared by all threads without storing other object references | ||
java Memory Analysis | Stack | Store the basic variable type (it will contain the specific value of this basic type) |
The variable of the reference object (the specific address of the reference in the heap will be stored) | ||
Method area | Can be shared by all threads | |
Contains all class and static variables |
The method area is a special heap.
Class loading process (understand)
When a program actively uses a class, if the class has not been loaded into memory, the system will initialize the class through the following three steps.
1. Class loading
Read the class file of the class into memory and create a java.lang.Class object for it. This is done by the class loader.
2. Class link
Merge the binary data of the class into the JRE.
3. Class initialization
The JVM is responsible for initializing the class.
Class loading and ClassLoader understanding
package reflection; public class Test05 { 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 link 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"); } } //Output results //Class A static code block initialization //Class A parameterless construction initialization //100
-
The above codes are stored in memory as follows:
First, the basic data of the class is generated in the method area. When the class is loaded, the class object has been generated in the heap.
Generate objects in the heap during new A (), and then find A's own class class (only one).
Class initialization
-
When does class initialization occur?
1. Active reference of class (class initialization must occur)
(1) When the virtual machine starts, initialize the class where the main method is located first
(2) new is an object of a class
(3) Call static members (except final constants) and static methods of the class
(4) Use the methods of the java.lang.reflect package to make reflection calls to the class
(5) When initializing a class, if its parent class is not initialized, its parent class will be initialized first
2. Passive reference of class (class initialization will not occur)
(1) 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. (the static variable has been completed when linking)
(2) Defining a class reference through an array does not trigger the initialization of this class
(3) 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)
//When will the test class initialize public class Test06 { static { System.out.println("Main Class is loaded"); } public static void main(String[] args) throws ClassNotFoundException { //1. Active call //(1) new is a class Son son = new Son(); //Output results //The Main class is loaded //The parent class is loaded //Subclass loaded //(2) Reflection also produces active references Class.forName("reflection.Son"); //Output results //The Main class is loaded //The parent class is loaded //Subclass loaded //2. Methods that do not generate class references //(1) Access the static domain of the parent class through the subclass System.out.println(Son.b); //Output results //The Main class is loaded //The parent class is loaded //2 //(2) Array, class will not be loaded (class reference is defined through array) Son[] array = new Son[5]; //Output results //The Main class is loaded //(3) Constants in constant pool System.out.println(Son.M); //Output results //The Main class is loaded //1 } } 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"); m = 300; } static int m = 100; static final int M = 1; }
Class loader
Role of 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 Java se class loader can find classes as required, but once a class is loaded into the loader, it will remain loaded (cached) for a period of time. However, the JVM garbage collection mechanism can recycle these class objects.
-
The class loader is used to load classes into memory. The JVM specification defines loaders for classes of the following types.
(1) Boot class loader
Written in C + +, it is the loader of the JVM. It is responsible for the Java platform core library (rt.java package) and is used to load the core class library. The loader cannot be obtained directly.
(2) Extended class loader
Be responsible for packaging the jar package under jre/lib/ext directory or the jar package under the directory specified by - D java.ext.dirs into the working library.
(3) System class loader
It is responsible for packing classes and jar s in the directory indicated by java -classpath or - D java.class.path. It is the most commonly used loader.
package reflection; public class Test07 { public static void main(String[] args) throws ClassNotFoundException { //Gets the loader of the system class ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); //Gets the parent class loader -- > extension class loader of the system class loader ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); //Get the parent class loader -- > root loader of the extension class loader (C/C + +) //The root loader (boot class loader) cannot get directly, so the result is null ClassLoader parent1 = parent.getParent(); System.out.println(parent1); //Test which class loads the current class (the custom class is loaded by the system loader) ClassLoader classLoader = Class.forName("reflection.Test07").getClassLoader(); System.out.println(classLoader); //Test who loaded the JDK built-in classes (root loader) 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")); } } //Output results //sun.misc.Launcher$AppClassLoader@18b4aac2 //sun.misc.Launcher$ExtClassLoader@74a14482 //null //sun.misc.Launcher$AppClassLoader@18b4aac2 //null /* C:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar; C:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar; D:\IntelliJ Idea\JavaSE\out\production\Basic grammar; D:\IntelliJ Idea\IntelliJ IDEA 2020.2.3\lib\idea_rt.jar */
Create an object for the runtime class
Gets the complete structure of the runtime class
-
Get the complete structure of the runtime class through reflection
Field,Method,Constructor,Superclass,Interface,Annotation
(1) All interfaces implemented
(2) Inherited parent class
(3) All constructors
(4) All methods
(5) All fields
(6) Annotation
(7).......
package reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; //Get class information public class Test08 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("reflection.User"); //User is an entity class //Find class by object //User user = new User(); //c1 = user.getClass(); //Get the name of the class System.out.println(c1.getName()); //Get package name + class name System.out.println(c1.getSimpleName()); //Get class name //Get the properties of the class //Only public properties can be found //Field[] fields = c1.getFields(); //All properties found Field[] fields = c1.getDeclaredFields(); for(Field field:fields){ System.out.println(field); } //Gets the value of the specified property Field name = c1.getDeclaredField("name"); System.out.println(name); //Method to get class System.out.println("=================================================="); Method[] methods = c1.getMethods(); //Get all methods of this class and its parent class for(Method method:methods){ System.out.println("natural:" + method); } methods = c1.getDeclaredMethods(); //Get all methods of this class for(Method method:methods){ System.out.println("getDeclaredMethods" + method); } //Gets the specified method //The latter requires parameters to represent the type of input parameters in the method, because the method has overloads to distinguish System.out.println("=================================================="); Method getName = c1.getMethod("getName",null); Method setName = c1.getMethod("setName",String.class); System.out.println(getName); System.out.println(setName); //Gets the specified constructor System.out.println("=================================================="); Constructor[] constructors = c1.getConstructors(); //Get public constructor for(Constructor constructor:constructors){ System.out.println(constructor); } constructors = c1.getDeclaredConstructors(); //Get all constructors for(Constructor constructor:constructors){ System.out.println("getDeclared" + constructor); } //Gets the specified constructor Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class,int.class); System.out.println("appoint:" + declaredConstructor); } } //reflection.User //User //private java.lang.String reflection.User.name //private int reflection.User.id //private int reflection.User.age //private java.lang.String reflection.User.name //================================================== //Normal: public java.lang.String reflection.User.toString() //Normal: public java.lang.String reflection.User.getName() //Normal: public int reflection.User.getId() //Normal: public void reflection.User.setName(java.lang.String) //Normal: public int reflection.User.getAge() //Normal: public void reflection.User.setAge(int) //Normal: public void reflection.User.setId(int) //Normal: public final void java.lang.Object.wait() throws java.lang.InterruptedException //Normal: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException //Normal: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException //Normal: public boolean java.lang.Object.equals(java.lang.Object) //Normal: public native int java.lang.Object.hashCode() //Normal: public final native java.lang.class (Java. Lang.Object. GetClass) //Normal: public final native void java.lang.Object.notify() //Normal: public final native void java.lang.Object.notifyAll() //getDeclaredMethodspublic java.lang.String reflection.User.toString() //getDeclaredMethodspublic java.lang.String reflection.User.getName() //getDeclaredMethodspublic int reflection.User.getId() //getDeclaredMethodspublic void reflection.User.setName(java.lang.String) //getDeclaredMethodspublic int reflection.User.getAge() //getDeclaredMethodspublic void reflection.User.setAge(int) //getDeclaredMethodspublic void reflection.User.setId(int) //================================================== //Gets the specified method //public java.lang.String reflection.User.getName() //public void reflection.User.setName(java.lang.String) //================================================== //Gets the specified constructor //public reflection.User() //public reflection.User(java.lang.String,int,int) //getDeclaredpublic reflection.User() //getDeclaredpublic reflection.User(java.lang.String,int,int) //Specify: public reflection.User(java.lang.String,int,int)
-
Summary:
(1) In the actual operation, the operation code to obtain the class information is not often developed
(2) Be familiar with the function and reflection mechanism of java.lang.reflect package
(3) How to get properties, methods, constructor names, modifiers, etc
What can I do with a Class object?
-
You can create a Class object: call the newInstance() method of the Class object
(1) Class must have a parameterless constructor
(2) The constructor of the class needs sufficient access rights
reflection? Can't you create an object without a parameterless constructor? As long as the constructor in the class is explicitly called during the operation and the parameters are passed in, the operation can be instantiated.
-
The steps are as follows:
(1) Get the specified parameter type constructor of this Class through getdeclaraedconstructor (Class... Parametertypes) of Class class
(2) Pass an object array into the formal parameters of the constructor, which contains all the parameters required by the constructor
(3) Instantiate objects through Constructor
-
Call the specified method
Through reflection, the Method in the class is called and completed through the Method class.
(1) Get a Method object through the getMethod(String name, Class... parameterTypes) Method of Class class, and set the parameter type required for this Method operation.
(2) Then use Object invoke(Object obj, Object[] args) to call and pass the parameter information of the obj object to be set to the method.
Object invoke(Object obj, Object[] args)
-
Object corresponds to the return value of the original method. If the original method has no return value, null is returned
-
If the original method is static, the formal parameter Object obj is null
-
If the original method parameter list is empty, Object[] args is null
-
If the original method is declared as private, you need to explicitly call the setAccessible(true) method of the method object before calling the invoke () method to access the private method
setAccessible
-
Method, Field and Constructor objects all have setAccessible methods.
-
setAccessible is a switch that enables and disables access security checks
-
If the parameter value is true, it indicates that the Java language access check should be cancelled when the reflected object is used
(1) Improve the efficiency of reflection. If reflection must be used in the code, and the code of this sentence needs to be called frequently, please set it to true
(2) So that private members that cannot be accessed can also be accessed
-
If the parameter is false, it indicates that the reflected object should implement Java language access check
package reflection; import javax.jws.soap.SOAPBinding; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; //Dynamically create objects through reflection public class Test09 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //Get Class object Class c1 = Class.forName("reflection.User"); //Construct an object //User user = (User)c1.newInstance(); //It was originally created as an Object class, which is strongly changed to User here //Essentially, a parameterless constructor is called! //System.out.println(user); // Output User{name='null', id=0, age=0} //Creating objects through constructors //Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,int.class); //User user2 = (User)constructor.newInstance("Qinjiang", 001,18); //System.out.println(user2); // Output User{name = 'Qinjiang', id=1, age=18} //Call normal methods through reflection User user3 = (User)c1.newInstance(); //Get a method by reflection Method setname = c1.getDeclaredMethod("setName", String.class); //invoke activates this method //(object, "value of method") setname.invoke(user3, "Mad God"); System.out.println(user3.getName()); //Output madness //Operation properties by reflection System.out.println("===========Operation properties by reflection============="); User user4 = (User)c1.newInstance(); Field name = c1.getDeclaredField("name"); //Private properties cannot be operated directly. You need to turn off the security detection of the program //Cancel security detection so that private properties can be accessed through reflection name.setAccessible(true); name.set(user4, "Mad god 2"); System.out.println(user4.getName()); //Output fury 2 } }
Performance comparison and analysis
package reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; //Analyze performance issues //The time taken for this method to execute 1 billion public class Test10 { //Normal mode call public static void test01(){ User user = new User(); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { user.getName(); } long endTime = System.currentTimeMillis(); System.out.println("Execute 1 billion in the normal way:" + (endTime-startTime) + "ms"); } //Reflection mode call public static void test02() 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 < 1000000000; i++) { getName.invoke(user, null); } long endTime = System.currentTimeMillis(); System.out.println("Execute 1 billion in reflection mode:" + (endTime-startTime) + "ms"); } //Reflection method call close check public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user = new User(); Class c1 = user.getClass(); Method getName = c1.getDeclaredMethod("getName", null); getName.setAccessible(true); long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000000; i++) { getName.invoke(user, null); } long endTime = System.currentTimeMillis(); System.out.println("Turn off the detection reflection mode and execute 1 billion of this:" + (endTime-startTime) + "ms"); } public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { test01(); test02(); test03(); //Execute 1 billion in ordinary way: 5ms //Reflection mode: 2811 MS //Turn off the detection reflection mode and execute 1 billion times: 1380ms } }
Reflection operation generics (understand)
-
Java uses the generic erasure mechanism to introduce generics. Generics in Java are only used by the compiler javac to ensure data security and avoid forced type conversion. However, once the compilation is completed, all types related to generics are erased.
-
In order to manipulate these types through reflection, Java has added ParameterizedType, GenericArrayType, TypeVariable and WildcardType to represent types that cannot be classified into Class but have the same name as the original type. (understand)
-
ParameterizedType: represents a parameterized type, such as collection < string > (generic type)
-
GenericArrayType: indicates that an element type is a parameterized type or an array type of type variable
-
TypeVariable: it is the public parent interface of each type variable
-
WildcardType: represents a wildcard type expression
package reflection; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; //Get generics through reflection public class Test11 { public void test01(Map<String, User> map, List<User> list){ System.out.println("test01"); } public Map<String, User> test02(){ System.out.println("test02"); return null; } public static void main(String[] args) throws NoSuchMethodException { Method method = Test11.class.getMethod("test01", Map.class, List.class); Type[] genericParameterTypes = method.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println("#" + genericParameterType); if(genericParameterType instanceof ParameterizedType){ //Judge whether genericParameterType belongs to parameterized type Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();//Get real parameter type for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } System.out.println(""); } //The output results are as follows: //#java.util.Map<java.lang.String, reflection.User> //class java.lang.String //class reflection.User // //#java.util.List<reflection.User> //class reflection.User method = Test11.class.getMethod("test02", null); Type genericReturnType = method.getGenericReturnType(); //Get return value type if(genericReturnType instanceof ParameterizedType){ //Determine whether genericReturnType is a parameterized type Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();//Get real parameter type for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } //Output results //class java.lang.String //class reflection.User } }
Reflection operation annotation
-
getAnnotations
-
getAnnotation
Practice ORM
-
What is ORM?
(1) Object relationship mapping -- > object relationship mapping
(2) Class corresponds to table structure
(3) Attribute corresponds to field
(4) Object corresponds to record
(5) Requirement: use annotation and reflection to complete the mapping relationship between class and table structure
package reflection; import java.lang.annotation.*; import java.lang.reflect.Field; //Practice reflection operation annotation public class Test12 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("reflection.Student2"); //Get annotations through reflection Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } //Output @ reflection.Tablekuang(value=db_student) //Gets the value of the annotated value //Annotation[] annotation = c1.getAnnotations(Tablekuang.class); Tablekuang tablekuang = (Tablekuang)c1.getAnnotation(Tablekuang.class); String value = tablekuang.value(); System.out.println(value); //Output db_student //Gets the annotation specified by the class Field f = c1.getDeclaredField("name"); //name or id or age Fieldkuang annotation = f.getAnnotation(Fieldkuang.class); System.out.println(annotation.columnName()); //Output db_name System.out.println(annotation.type()); //Output varchar System.out.println(annotation.length()); //Output 3 } } @Tablekuang("db_student") class Student2{ @Fieldkuang(columnName = "db_id",type = "int",length = 10) private int id; @Fieldkuang(columnName = "db_age",type = "int",length = 10) private int age; @Fieldkuang(columnName = "db_name",type = "varchar",length = 3) private String name; public Student2() { } public Student2(int id, int age, String name) { this.id = id; this.age = age; 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; } 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) //Act on class @Retention(RetentionPolicy.RUNTIME) @interface Tablekuang{ //value is equivalent to the table name String value(); } //Attribute annotation @Target(ElementType.FIELD) //Act on attributes @Retention(RetentionPolicy.RUNTIME) @interface Fieldkuang{ String columnName(); String type(); int length(); }