01. What is annotation
- Annotation is from jdk5 New technologies introduced from 0
- Function of Annotation
- Not the program itself, you can explain the program (this is no different from comments)
- 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
02. Built in annotation
- @Override: defined in Java In lang. override, this annotation is only applicable to modified methods, indicating that one method declaration intends to override another method declaration in the superclass.
- Deprecated: defined in Java In lang. deprecated, this annotation can be used to modify methods, attributes and classes, indicating that programmers are not encouraged to use such elements, usually because it is dangerous or there are better choices
- @SuppressWarnings: defined in Java Lang. SuppressWarnings, used to suppress warnings at compile time
- @SuppressWarning("all")
- @SuppressWarning("unchecked")
- @SuppressWarnings(value={"unchecked","deprecation"})
- ...
package com.chenchuyi.demo5; public class TestAnnotation { public static void main(String[] args) { TestAnnotation.run(); } //override method @Override public String toString() { return super.toString(); } //Programmers are not encouraged to use it, but it is still available @Deprecated public static void run(){ System.out.println("How do you do"); } //Suppress compiled warnings @SuppressWarnings("all") public void go(){ System.out.println("123"); } }
03. Meta note
- The function of meta annotation is to annotate other annotations. java defines four standard Mata annotation types, which are used to describe other annotation types.
- These types and the classes they pay for are in Java Lang.annotation package (@ target, @ retention, @ docummented, @ inherited)
- @Target: used to describe the scope of use of annotations (i.e. where the described annotations can be used)
- @Retention: indicates where the annotation is still valid. It is used to describe the lifecycle of the annotation (source < class < runtime)
- @Document: note that the annotation will be included in the javadoc
- @Inherited: indicates that the subclass can inherit the annotation in the parent class
Custom annotation
package com.chenchuyi.demo5; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @mygo public class metaAnnotation { @mygo public void goooo(){} } //Custom annotation //METHOD is used in the METHOD //TYPE is used in a class @Target({ElementType.METHOD,ElementType.TYPE}) //RUNTIME>CLASS>SOURCE @Retention(RetentionPolicy.RUNTIME) @interface mygo{}
@The selectable values for Target are
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Formal parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE }
@The selectable values for Retention are
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
04. Custom annotation
- When you use @ interface to customize annotations, you automatically inherit Java 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 parameter type (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 com.chenchuyi.demo5; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class Annotation2 { @myAnnotation1(name = "1") public void run1(){} @myAnnotation2(19) public void run2(){} } //Custom annotation @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface myAnnotation1{ //Annotated parameters: parameter type + parameter name (); //Define a string String name(); //The default value will not be written in the comment int age() default 18; //Define an array int[] num() default {12,18}; } //Custom annotation @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface myAnnotation2{ //Annotated parameters: parameter type + parameter name (); //If only one parameter is defined, the parameter name can be written as values. The parameter name of value can be omitted for the parameter in the annotation. If multiple parameters are defined, they cannot be omitted int value(); }
05. Reflection overview
Dynamic language
- **Dynamic language (weakly typed language) * * is a language that determines the data type only at run time. There is no need to declare the type of a variable before use. Usually, the value of a variable is the type of the value assigned. For example, Php, Asp, JavaScript, Python, Perl, and so on.
var s ="hello"; var i = 0; var b = true;
Static language
- **Static language (strongly typed language) * * is a language that can determine the data type of variables at compile time. Most static languages require that the data type of variables must be specified before using variables. For example, Java, C, C + +, C # and so on.
- 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!
String s="hello"; //Variable of type String boolean b=true; //Variables of type boolean int i=0; //Variable of type int
Java Reflection
- Java reflection mechanism is in the running state, for any class, you can know all the properties and methods of this class, and for any object, you can call any of its methods and properties. This dynamically obtained information and the function of dynamically calling the methods of the object are called the reflection mechanism of Java language.
- 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
06. 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
- . . .
Advantages and disadvantages of Java reflection
advantage:
- It can dynamically create objects and compile, reflecting great flexibility
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
- 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 a class
- ...
Class class
This class is used to manipulate (reverse parse) the properties, methods, constructors, etc. of a class.
Person: name, age, address (as long as class knows your person class, it can know all your attributes, not only attributes, but even annotation on methods.)
public class Test01 { public static void main(String[] args) { try { Class<?> c1 = Class.forName("kuangJava.reflects.User"); System.out.println(c1); Class<?> c2 = Class.forName("kuangJava.reflects.User"); Class<?> c3 = Class.forName("kuangJava.reflects.User"); System.out.println(c2.hashCode()); System.out.println(c3.hashCode()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } //An entity class is a constructor with the or with theout parameters, such as get, set, and toString, as long as it has simple properties class User { private int id; private String name; public User() { } 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; } }
output
class kuangJava.reflects.User
895328852
895328852
07. Several ways to get Class
Class class
-
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 has only one Class instance in the JVM
- A class object corresponds to a class 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.
Common methods of Class
Get an instance of Class
- 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 the program performance is the highest
Class clazz = Person.class;
- If an instance of a Class is known, call the getClass() method of the instance to obtain the Class object
Class clazz = person.getClass();
- The full Class name of a Class is known, and the Class can be obtained through the static method forName() of Class class under the Class path, and ClassNotFoundException can be thrown
Class clazz = Class.forName("demo01.Student");
- The built - in basic data type can use the class name directly Type
- You can also use ClassLoader (explained later)
package com.chenchuyi.demo5; @SuppressWarnings("all") public class getclassType { public static void main(String[] args) throws ClassNotFoundException { Person stu = new Student("Chen Chu"); System.out.println("This is:"+stu.name); //Obtained by object Class c1 = stu.getClass(); System.out.println(c1); //Obtained by forName Class c2 = Class.forName("com.chenchuyi.demo5.Student"); System.out.println(c2); //By class name Class get Class c3 = Student.class; System.out.println(c3); //Wrapper classes of basic built-in types have a Type attribute Class c4 = Integer.TYPE; System.out.println(c4); //Get the parent class name from the child class name Class superclass1 = c1.getSuperclass(); System.out.println(superclass1); Class superclass2 = c2.getSuperclass(); System.out.println(superclass2); } } class Person{ public String name; public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } //student class Student extends Person{ public Student(String name) { super(name); } } //teacher class Teacher extends Person{ public Teacher(String name) { super(name); } }
output
This is Chen Chu class com.chenchuyi.demo5.Student class com.chenchuyi.demo5.Student class com.chenchuyi.demo5.Student int class com.chenchuyi.demo5.Person class com.chenchuyi.demo5.Person
08. Class objects of all types
What types can have Class objects
- Class: external class, member (member internal class, static internal class), local internal class, anonymous internal class
- interface: interface
- []: array
- enum: Enumeration
- Annotation: annotation @ interface
- primitive type: basic data type
- void
package com.chenchuyi.demo5; import java.lang.annotation.ElementType; @SuppressWarnings("all") public class TestClass { public static void main(String[] args) { Class c1 = Object.class;//class Class c2 = Comparable.class;//Interface Class c3 = String[].class;//One dimensional array Class c4 = String[][].class;//Two dimensional array Class c5 = Override.class;//annotation Class c6 = ElementType.class;//enumeration Class c7 = Integer.class;//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); //As long as the element type (int) is the same as the dimension (one-dimensional or two-dimensional), it 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()); } }
output
class java.lang.Object interface java.lang.Comparable class [Ljava.lang.String; class [[Ljava.lang.String; interface java.lang.Override class java.lang.annotation.ElementType class java.lang.Integer void class java.lang.Class 356573597 356573597
09. Class loading memory analysis
Class loading process
Class loading and ClassLoader understanding
- Load: 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. Net file representing this class Lang.class object
- Link: the process of merging the binary code of Java classes into the running state of the JVM
- Verification: ensure that the loaded class information complies with the JVM specification and there are no security problems
- Preparation: the stage of formally allocating memory for class variables (static) and setting the default initial value of class variables. These memory will be allocated in the method area
- Resolution: the process of replacing the symbolic reference (constant name) in the virtual machine constant pool with a direct reference (address)
- initialization:
- The process of executing a class constructor () method. The class constructor () method is generated by the combination of the assignment action of the compiler automatically collecting class variables and the statements in the static code block. (the class constructor is used to construct class information, not the constructor to construct the class object)
- When initializing a class, if it is found that its parent class has not been initialized, the initialization of its parent class needs to be triggered first
- Virtual chance ensures that the () methods of a class are properly locked and synchronized in a multithreaded environment
public class Test05 { public static void main(String[] args) { A a = new A(); System.out.println(A.n); } } class A { static { n = 300; System.out.println("A Class"); } static int n = 100; { System.out.println("A Code block for class"); } public A() { System.out.println("A Class construction method"); } }
output
A Class A Code block for class A Class construction method 100
10. Analysis class initialization
When does class initialization occur
- 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
- Using Java The method of lang.reflect package makes 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 class when they are linked)
The following five cases can be opened separately for practice
public class Test06 { static { System.out.println("Main Class is loaded"); } public static void main(String[] args) { //1. Active reference // Son son = new Son(); //2. Reflection also produces active references // try { // Class.forName("kuangJava.reflects.Son"); // } catch (ClassNotFoundException e) { // e.printStackTrace(); // } //A method that does not generate a reference to a class //3. // System.out.println(Son.b); //4. // Son[] sons = new Son[2]; //5. System.out.println(Son.M); } } class Father { static int b = 2; static { System.out.println("Parent static code block"); } } class Son extends Father { static { System.out.println("Subclass static code block"); m = 300; } static int m = 100; static final int M = 1; } summary: 1.If you call constants of your own class through your own class, initialization will not occur 2.The subclass will not be initialized by calling the static variable or constant of the parent class through the subclass
output
1. Main Class is loaded Parent static code block Static subclass code 2. Main Class is loaded Parent static code block Subclass static code block 3. Main Class is loaded Parent static code block 2 4. Main Class is loaded 5. Main Class is loaded 1
11. Class loader
Role of class loader
- The function of class loading: load the bytecode content of the class file into memory, replace these static data with the runtime data structure of the method area, and then generate a Java. Net file representing this class in the heap Lang. class object, as the access entry of 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 class loader, it will remain loaded (cached) for a period of time. However, the JVM garbage collection mechanism can recycle this class object
Role of class loader
class loader is used to load classes into memory. The JVM specification defines loaders for classes of the following types
public class Test07 { public static void main(String[] args) { //Get system class loader ClassLoader classLoader = ClassLoader.getSystemClassLoader(); System.out.println(classLoader); //Get the parent class loader of the system class loader -- extended class loader ClassLoader extendClassLoader = classLoader.getParent(); System.out.println(extendClassLoader); //Get the parent class loader of the extension class loader -- root loader (C + +) ClassLoader rootClassLoader = extendClassLoader.getParent(); System.out.println(rootClassLoader); try { //Gets which loader loaded the current class ClassLoader classLoader1 = Class.forName("kuangJava.reflects.Test07").getClassLoader(); System.out.println(classLoader1); //Get which loader loaded the JDK built-in class ClassLoader classLoader2 = Class.forName("java.lang.Object").getClassLoader(); System.out.println(classLoader2); } catch (ClassNotFoundException e) { e.printStackTrace(); } //How to get the loading path of the system class loader //System.out.println(System.getProperty("java.class.path")); /** * D:\software\Java\jdk1.8.0_241\jre\lib\charsets.jar * D:\software\Java\jdk1.8.0_241\jre\lib\deploy.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\access-bridge-64.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\cldrdata.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\dnsns.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\jaccess.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\jfxrt.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\localedata.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\nashorn.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\sunec.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\sunjce_provider.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\sunmscapi.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\sunpkcs11.jar * D:\software\Java\jdk1.8.0_241\jre\lib\ext\zipfs.jar * D:\software\Java\jdk1.8.0_241\jre\lib\javaws.jar * D:\software\Java\jdk1.8.0_241\jre\lib\jce.jar * D:\software\Java\jdk1.8.0_241\jre\lib\jfr.jar * D:\software\Java\jdk1.8.0_241\jre\lib\jfxswt.jar * D:\software\Java\jdk1.8.0_241\jre\lib\jsse.jar * D:\software\Java\jdk1.8.0_241\jre\lib\management-agent.jar * D:\software\Java\jdk1.8.0_241\jre\lib\plugin.jar * D:\software\Java\jdk1.8.0_241\jre\lib\resources.jar * D:\software\Java\jdk1.8.0_241\jre\lib\rt.jar * D:\IdeaProjects\mystudy\target\classes * D:\mavenRepository\org\apache\httpcomponents\httpclient\4.5.12\httpclient-4.5.12.jar * D:\mavenRepository\org\apache\httpcomponents\httpcore\4.4.13\httpcore-4.4.13.jar * D:\mavenRepository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar * D:\mavenRepository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar * D:\mavenRepository\org\apache\poi\poi\4.1.2\poi-4.1.2.jar * D:\mavenRepository\org\apache\commons\commons-collections4\4.4\commons-collections4-4.4.jar * D:\mavenRepository\org\apache\commons\commons-math3\3.6.1\commons-math3-3.6.1.jar * D:\mavenRepository\com\zaxxer\SparseBitSet\1.2\SparseBitSet-1.2.jar * D:\mavenRepository\org\apache\poi\poi-ooxml\4.1.2\poi-ooxml-4.1.2.jar * D:\mavenRepository\org\apache\poi\poi-ooxml-schemas\4.1.2\poi-ooxml-schemas-4.1.2.jar * D:\mavenRepository\org\apache\xmlbeans\xmlbeans\3.1.0\xmlbeans-3.1.0.jar * D:\mavenRepository\org\apache\commons\commons-compress\1.19\commons-compress-1.19.jar * D:\mavenRepository\com\github\virtuald\curvesapi\1.06\curvesapi-1.06.jar * D:\mavenRepository\com\alibaba\fastjson\1.2.73\fastjson-1.2.73.jar * D:\mavenRepository\commons-io\commons-io\2.8.0\commons-io-2.8.0.jar * D:\software\ideaIU-2019.3.3.win\lib\idea_rt.jar */ } }
output
sun.misc.Launcher$AppClassLoader@18b4aac2 sun.misc.Launcher$ExtClassLoader@355da254 null sun.misc.Launcher$AppClassLoader@18b4aac2 null
12. Get the runtime structure of the class
Gets the complete structure of the runtime class
Get the complete structure of the runtime class through reflection
Field Method Construtor Superclass Interface Annotation
- All interfaces implemented
- Inherited parent class
- All constructors
- All methods
- All fields
- annotation
- . . .
public class Test08 { public static void main(String[] args) { try { Class<?> c1 = Class.forName("kuangJava.reflects.User"); //Gets the name of the class System.out.println(c1.getName()); //Get package name + class name System.out.println(c1.getSimpleName()); System.out.println("========"); //Class name //Gets the properties of the class Field[] fields = c1.getFields(); //--Only public properties can be found fields = c1.getDeclaredFields();//--Find all properties for (Field field : fields) { System.out.println(field); } Field nameField = c1.getDeclaredField("name");//--Gets the value of the specified property System.out.println(nameField); //Method to get class Method[] methods = c1.getMethods(); //--Get all public methods of this class and its parent class for (Method method : methods) { System.out.println("===getMethods==="+method); } methods = c1.getDeclaredMethods(); //Get all methods of this class for (Method method : methods) { System.out.println("===getDeclaredMethods==="+method); } Method getName = c1.getDeclaredMethod("getName", null); //--Gets the specified method Method setName = c1.getDeclaredMethod("setName", String.class); System.out.println(getName); System.out.println(setName); //Gets the specified constructor Constructor<?>[] constructors = c1.getConstructors(); //Get all constructors of public for (Constructor<?> constructor : constructors) { System.out.println("===getConstructors==="+constructor); } constructors = c1.getDeclaredConstructors();//Gets the constructor of this class for (Constructor<?> constructor : constructors) { System.out.println("===getDeclaredConstructors==="+constructor); } Constructor<?> declaredConstructor = c1.getDeclaredConstructor(int.class, String.class);//Gets the specified constructor System.out.println("Specify constructor:"+declaredConstructor); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } class User { private int id; private String name; public User() { } public User(int id, String name) { this.id = id; this.name = name; } 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; } private void test() { } }
output
kuangJava.reflects.User User ======== private int kuangJava.reflects.User.id private java.lang.String kuangJava.reflects.User.name private java.lang.String kuangJava.reflects.User.name ===getMethods===public java.lang.String kuangJava.reflects.User.getName() ===getMethods===public int kuangJava.reflects.User.getId() ===getMethods===public void kuangJava.reflects.User.setName(java.lang.String) ===getMethods===public void kuangJava.reflects.User.setId(int) ===getMethods===public final void java.lang.Object.wait() throws java.lang.InterruptedException ===getMethods===public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException ===getMethods===public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException ===getMethods===public boolean java.lang.Object.equals(java.lang.Object) ===getMethods===public java.lang.String java.lang.Object.toString() ===getMethods===public native int java.lang.Object.hashCode() ===getMethods===public final native java.lang.Class java.lang.Object.getClass() ===getMethods===public final native void java.lang.Object.notify() ===getMethods===public final native void java.lang.Object.notifyAll() ===getDeclaredMethods===public java.lang.String kuangJava.reflects.User.getName() ===getDeclaredMethods===public int kuangJava.reflects.User.getId() ===getDeclaredMethods===public void kuangJava.reflects.User.setName(java.lang.String) ===getDeclaredMethods===private void kuangJava.reflects.User.test() ===getDeclaredMethods===public void kuangJava.reflects.User.setId(int) public java.lang.String kuangJava.reflects.User.getName() public void kuangJava.reflects.User.setName(java.lang.String) ===getConstructors===public kuangJava.reflects.User() ===getConstructors===public kuangJava.reflects.User(int,java.lang.String) ===getDeclaredConstructors===public kuangJava.reflects.User() ===getDeclaredConstructors===public kuangJava.reflects.User(int,java.lang.String) Specify constructor: public kuangJava.reflects.User(int,java.lang.String)
13. Dynamically create object execution methods
What can I do with a Class object?
- Create Class object: call newInstance() method of Class object
- Class must have a parameterless constructor
- The constructor of the class must have sufficient access rights
Think: 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:
- Get the constructor of the specified parameter type of this Class through getdeclaraedconstructor (Class... parameterTypes) of Class class
- Pass an object array into the formal parameters of the constructor, which contains all the parameters required by the constructor
- Instantiate objects through Constructor
Call the specified method
Through reflection, the Method in the class is called and implemented through the Method class
- 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.
- 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 can be 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 scheme 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
- 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
- Make the original private members inaccessible
- If the parameter value is false, it indicates that the reflected object should implement java language access check
public class Test09 { public static void main(String[] args) { try { //Get Class object Class c1 = Class.forName("kuangJava.reflects.User"); //1. Construct an object (essentially calling the class's parameterless constructor) // User user = (User) c1.newInstance(); // System.out.println(user); //2. Create objects through constructors // Constructor constructor = c1.getDeclaredConstructor(int.class, String.class); // User user2 = (User) constructor.newInstance(18, "zyy"); // System.out.println(user2); //3. Call common methods through reflection User user3 = (User) c1.newInstance(); //Get a method by reflection Method setName = c1.getDeclaredMethod("setName", String.class); //invoke: the meaning of activation (object, "method value") setName.invoke(user3, "zyy"); System.out.println(user3.getName()); //Reflection static method Method print = c1.getDeclaredMethod("print", String.class); print.invoke(null, "hello"); //4. Operate attributes through reflection User user4 = (User) c1.newInstance(); Field name = c1.getDeclaredField("name"); //Private properties cannot be operated directly. We need to turn off the security monitoring of the program, and setAccessible(true) of properties or methods name.setAccessible(true); name.set(user4, "zyy2"); System.out.println(user4.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } } } class User { private int id; private String name; public User() { } public User(int id, String name) { this.id = id; this.name = name; } 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; } private void test() { } public static void print (String msg) { System.out.println("print:"+msg); } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
14. Performance comparison and analysis
package com.chenchuyi.demo7; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class TestTime { //Common method public static void test01() { Users users = new Users(); long starttime = System.currentTimeMillis(); for (int i = 0; i <= 1000000000; i++) { users.run(18); } long endtime = System.currentTimeMillis(); System.out.println("General:"+(endtime - starttime)+"ms"); } //reflex public static void test02() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { Users users = new Users(); Class c1 = users.getClass(); Method run = c1.getDeclaredMethod("run",int.class); long starttime = System.currentTimeMillis(); for(int i = 0;i<=10000000;i++){ run.invoke(users,18); } long endtime = System.currentTimeMillis(); System.out.println("Reflection:"+(endtime - starttime)+"ms"); } //The reflection method closes the detection program public static void test03() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { Users users = new Users(); Class c1 = users.getClass(); Method run = c1.getDeclaredMethod("run",int.class); run.setAccessible(true); long starttime = System.currentTimeMillis(); for(int i = 0;i<=10000000;i++){ run.invoke(users,18); } long endtime = System.currentTimeMillis(); System.out.println("reflex+close:"+(endtime - starttime)+"ms"); } public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { test01(); test02(); test03(); } }
output
Normal: 8 ms Reflection: 76 ms reflex+Off: 73 ms
15. Get generic information
Reflection operation generics
- 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 adds ParameterizedType,GenericArrayType,TypeVariable and WildcardType to represent types that cannot be classified into Class but have the same name as the original type
- ParameterizedType: represents a parameterized type, such as Collection
- GenericArrayType: indicates that an element type is an array type of parameterized type or type variable
- TypeVariable: it is the public parent interface of various types of variables
- WildcardType: represents a wildcard type expression
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) { try { System.out.println("Print test01 Generics of method parameters"); Method method = Test11.class.getDeclaredMethod("test01", Map.class, List.class); Type[] genericParameterTypes = method.getGenericParameterTypes(); for (Type genericParameterType : genericParameterTypes) { System.out.println("#"+genericParameterType); if (genericParameterType instanceof ParameterizedType) { Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } System.out.println("Print test02 Generic type of return value"); method = Test11.class.getDeclaredMethod("test02"); Type genericReturnType = method.getGenericReturnType(); System.out.println("#"+genericReturnType); if (genericReturnType instanceof ParameterizedType) { Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } catch (NoSuchMethodException e) { e.printStackTrace(); } } }
output
Print test01 Generics of method parameters #java.util.Map<java.lang.String, kuangJava.reflects.User> class java.lang.String class kuangJava.reflects.User #java.util.List<kuangJava.reflects.User> class kuangJava.reflects.User Print test02 Generic type of return value #java.util.Map<java.lang.String, kuangJava.reflects.User> class java.lang.String class kuangJava.reflects.User
16. Get annotation information
Reflection operation annotation
- getAnnotations
- getAnnotation
package com.chenchuyi.demo7; import org.omg.Messaging.SYNC_WITH_TRANSPORT; import java.lang.annotation.*; import java.lang.reflect.Field; @SuppressWarnings("all") public class getAnnotation { public static void main(String[] args) throws NoSuchFieldException { //Get annotations through reflection Class c1 = test.class; Annotation[] annotations = c1.getAnnotations(); for(Annotation annotation : annotations){ System.out.println("Get annotations through reflection:"+annotation); //Gets the value of the annotated value if(annotation instanceof TableStudent){ System.out.println("Get the value of the annotation through reflection:"+((TableStudent) annotation).value()); } } //Gets the annotation specified by the class Field name = c1.getDeclaredField("name"); FieldStudent annotation = name.getAnnotation(FieldStudent.class); System.out.println("Get the annotation specified by the class:"+annotation.columnName()); System.out.println("Get the annotation specified by the class:"+annotation.length()); System.out.println("Get the annotation specified by the class:"+annotation.type()); } } //Class name annotation @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface TableStudent{ String value(); } //Attribute annotation @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface FieldStudent { String columnName(); String type(); int length(); } @TableStudent("db_Student") class test{ @FieldStudent(columnName = "id", type = "int", length = 30) private int id; @FieldStudent(columnName = "name", type = "varchar", length = 20) private String name; @FieldStudent(columnName = "age", type = "int", length = 3) private int age; public test() {} public test(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } 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; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "getAnnotation{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
output
Get annotations through reflection:@com.chenchuyi.demo7.TableStudent(value=db_Student) Get the value of the annotation through reflection: db_Student Get the annotation specified by the class: name Get the annotation specified by the class: 20 Get the annotation specified by the class: varchar