Reflection is an important part of The Java language, reflection can dynamically perform access to classes, methods and fields during the runtime, will greatly improve the flexibility of the framework, so like many open source frameworks use a lot of reflection to dynamically generate objects, such as Spring bean, Mybatis Mapper. But reflection has been criticized for its performance. How many ways can you create objects in Java? 1. Use the new keyword 2. Use the clone method 3. 5. Use Unsafe

1. A small demo that instantiates the object using reflection and calls the method 1.1 in the object to define a Student object

/** * @Author feng ye * @Date 2021/6/30 0:48 * @Description */ public class Student { public void toSleep(){ System.out.println("toSleep method executed... ); }}Copy the code

1.2 Defining a properties file The content is the fully qualified name of the class and the methods in the class

1.3 Read configuration file species information, use reflection to instantiate Student object and call toSleep method

/** * @Author feng ye * @Date 2021/6/30 0:41 * @Description */ public class ReadSource { public static void Main (String[] args) throws Exception{// An object of any class can be created, and any methods can be executed. Properties pro = new Properties(); / / 1.2 loading configuration files, into a collection / / 1.2.1 get class configuration files in the directory this this = ReadSource. Class. GetClassLoader (); InputStream is = classLoader.getResourceAsStream("pro.properties"); pro.load(is); String className = pro.getProperty("className"); //2. String methodName = pro.getProperty("methodName"); Class CLS = class.forname (className); Obj = cls.newinstance (); Method = cls.getMethod(methodName); Method[] methods = cls.getMethods(); System.out.println("methods.length :"+ methods.length); For (Method m: methods){system.out.println (" cls.getSimplename ()+", "Method "+m.getName()); } //6. Invoke method.invoke(obj); }}Copy the code

Execution Result:This is how reflection and SPI can be used to dynamically generate objects. We just need to replace the class name and method name in the configuration file

2. Reflection Class object explanation

There are three ways to get a class object, and they’re all different ways to get the same class object. Because class files are only loaded by the JVM once

1. Get member variables * Field[] getFields() : Field getField(String name) getDeclaredFields() getDeclaredFields() getDeclaredFields() getDeclaredFields() getDeclaredFields() Field getDeclaredField(String name) 2. Get constructors * Constructor<? >[] getConstructors() * Constructor<T> getConstructor(class <? >... ParameterTypes * Constructor<T> getDeclaredConstructor(class <? >... parameterTypes) * Constructor<? >[] getDeclaredConstructors() 3. GetMethod (String name, class <? >... ParameterTypes) * Method[] getDeclaredMethods() * Method getDeclaredMethod(String name, class <? >... ParameterTypes * String getName();Copy the code

Field object operations 3.1 Define a Person class

``` public class Person { public String a; protected String b; String c; String d = "I am d"; private int age; private String name; public Person(int age, String name) { this.age = age; this.name = name; } public Person() { } private Person(String name) { this.name = name; } public void show() {system.out.println ("show method executed "); } private void show2() {system.out.println (" private show2 method is executed "); } 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 "Person{" + "a='" + a + ''' + ", b='" + b + ''' + ", c='" + c + ''' + ", d='" + d + ''' + ", age=" + age + ", name='" + name + ''' + '}'; } public void eat() { System.out.println("eat..." ); } public void eat(String food) { System.out.println("eat..." + food); } private void sum(Integer num) {system.out.println ("sum is executed... + num); }} ` ` `Copy the code

3.2 Using reflection to access permission-free properties in a class and assign values to them

/** * @author feng ye * @date 2021/6/30 0:23 * @description use reflection to get a member variable of the Class object. [public,protected,private] */ public class ReflectDemo02 {/** * Field[] getFields() * Field getField(String name) * Field[] getDeclaredFields() * Field getDeclaredField(String name) */ public static void main(String[] args) throws Exception { //0. Class personClass = person.class; * Field[] getFields() * Field getField(String name) * Field[] getDeclaredFields() * Field Field[] fields = personClass.getFields(); getDeclaredField(String name) */ /1.Field[] getFields(); For (Field Field: fields) {system.out.println (" traversal to get all public modifier member variables Field: "+ Field); } //2.Field getField(String name) Field a = personClass.getField("a"); Person p = new Person(); Object value = a.get(p); System.out.println(" Get person attribute A name: "+value); // set a to a.set(p, "zhang SAN "); System.out.println(" Set person property a value: "+ p); System. The out. Println (" # # # # # # # # # # # # # delimiter # # # # # # # # # # # # "); / / Field [] getDeclaredFields () : obtain all member variables, regardless of the modifier Field [] declaredFields = personClass. GetDeclaredFields (); For (Field declaredField: declaredFields) {/ / open access to violence, access to private property of a class declaredField. SetAccessible (true); Object a1 = declaredField.get(p); System.out.println("--------------->a1: " + a1); System.out.println("--------------->declaredField: " + declaredField); } //Field getDeclaredField(String name) Field d = personClass.getDeclaredField("d"); // Security check for ignoring access modifiers d.setaccessible (true); // Object value2 = d.set (p); System.out.println(" Get the value of d in the Person class: "+value2); }}Copy the code

The execution result

4. Launch methods in the access class

Public class ReflectDemo04 {/** * class object function: * Method[] getMethods() * Method getMethod(String name, class <? >... parameterTypes) * Method[] getDeclaredMethods() * Method getDeclaredMethod(String name, Class<? >... ParameterTypes) * */ gets the class name * String getName() */ public static void main(String[] args) throws Exception {//0. Class personClass = person.class; Eat_method = personclass.getMethod ("eat"); Person p = new Person(); // invoke eat_method.invoke(p); Method eat_method2 = personClass.getMethod("eat", String.class); // invoke eat_method2.invoke(p, "rice "); System. The out. Println (" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- separator 1 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "); [] methods = personClass.getMethods(); For (Method Method: methods) {system.out.println (" Get all public methods, methodName: "+ Method); } System. Out. Println (" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the delimiter 2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "); / / to get private modified sum Method sum = personClass. GetDeclaredMethod (" sum ", Integer. Class); sum.setAccessible(true); sum.invoke(p,1); }Copy the code

Execution Result:

5. Why does reflection slow down? Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications. The type of reflection is dynamically resolved, which prevents the JVM from performing certain optimizations (more specifically, JIT optimizations), and should be avoided for performance-sensitive and frequently invoked methods.

5.1 static and dynamic loading: here is a clssload_.java file we wrote with notePad++, and then tried to use CMD to javac. Statically loaded: The Java files we wrote are compiled into class bytecode files at compile time. Since Dog is statically loaded, an exception will be thrown if the class does not exist.

Dynamic loading: Person is dynamically loaded, so no errors are reported at compile time even if the Person does not exist. An error will only be reported if the Person class is loaded dynamically at case “2”.

Conclusion: One conclusion can be drawn (why reflection is slow and affects performance). Reflection loads the object’s bytecode file into the JVM only when it is dynamically loaded. Also, there are time judgments such as security checks when accessing reflective properties. Dynamic loading can be compared to lazy loading of Java objects, because the dynamic loading process needs to do something, so it is slow.

Reflection optimization: