Hello, today I’m going to share with you Java reflection, so take out your little book and write it down

Reflective overview

What is reflection

The process of encapsulating the components of a class into other objects is called reflection. The components refer to our class’s fields, constructors, and methods.

Pros and cons of using reflection

advantages

  • The class object can be operated during the program running, which increases the flexibility of the program.
  • Decoupling, so as to improve the scalability of the program, improve the code reuse rate, convenient external call;
  • For any class, when you know its class name, you can know all the attributes and methods of that class. For any object, one of its methods can be called.

disadvantages

  • Performance issues: Java reflection contains dynamic types that cannot be optimized by the JVM, so operating through reflection is less efficient than normal.
  • Security issues: The use of reflection requires that the program must run in an environment with no security restrictions. If the program has security restrictions, reflection cannot be used.
  • Program robustness: Reflection allows code to perform actions that are not normally allowed, breaking the abstraction of program structure and making the abstract logical structure unrecognizable when the platform changes.

Getting and using the Class object

How to get a Class object

Class. ForName (” full name “)

Source code stage, it can load the bytecode file into memory, and then return the Class object, mostly used in the configuration file, define the Class name in the configuration file, by reading the configuration file to load the Class.

2. The name of the class. The class

Class object stage, through the class attribute of the class name to obtain, mostly used for parameter passing.

3. Object. GetClass ()

At run time, getClass() is defined in the Object class, indicating that all classes can use this method, which is mostly used to get bytecodes for objects.

We’ll start by defining a Person class for subsequent reflection testing.

Once the Person Class is defined, we try to get the Class objects in three different ways and compare them to see if they are the same.

In the above code, you can see that the final comparison result returns two true, indicating that the Class object obtained by the above three methods is the same, and the same bytecode file (*.class) is loaded only once during a run.

The use of Class objects

Get member variables

Field[] getFields()

If you look back at the Person class, you can see that the id and grade member variables are all decorated by public, indicating that this method is used to get all member variables in the class that are decorated by public (including the parent class).

Field getField(String name)

From the above analysis, we can see that this method can only be used to get the public variable of the specified name in the class. For protected and private variable, this method is not available (including the parent class). To obtain or set the value of a member variable, you can use the get/set method as follows.

Field[] getDeclaredFields()

As you can see from the above results, this method can be used to get all member variables, regardless of modifiers (excluding the parent class).

Field getDeclaredField(String name)

As you can see from the above, this method can be used to get a specified member variable, regardless of the limitations of the member variable modifier (excluding the parent class). However, when using the set and get methods to get and set private and protected member variables, you need to use setAccessible() to ignore the security check for accessing the new modifiers, otherwise the program will report an error.

Get constructor

package com.cunyu;

import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;

/ * *

  • @author : cunyu
  • @version : 1.0
  • @className : Demo3
  • @date : 2021/4/8 13:28
  • @description: Construct object fetch

* /

public class Demo3 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class personClass = Class.forName(“com.cunyu.Person”);

System.out.println(” all constructors “); Constructor[] constructors = personClass.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); }

// get the specified constructor

// empty parameter constructor system.out.println (” empty parameter constructor “); Constructor constructor1 = personClass.getConstructor(); System.out.println(constructor1); Println (” parameterized constructor “); // System.out.println(” parameterized constructor “); Constructor constructor2 = personClass.getConstructor(int.class, String.class, long.class, long.class, float.class, int.class); System.out.println(constructor2);

Println (” void argument creates object “); Object person = constructor1.newinstance (); System.out.println(person); Object person1 = personclass.newinstance (); System.out.println(person1);

System.out.println(" create object with arguments "); Constructor2. NewInstance (20, "village yuyao ", 1312020, 3, 99.0f, 2); System.out.println(object); }Copy the code

}

Similar to getting a member variable from a Class instance, this method is used to get all constructors (including the parent Class) decorated by public;

Constructor getConstructor (class <? >… parameterTypes)

This method is used to get the constructor (including the parent class) that public modifies after a specified parameter type.

Constructor<? >[] getDeclaredConstructors()

This method is used to get all constructors modified by public (excluding the parent class);

Constructor getDeclaredConstructor (class <? >… parameterTypes)

This method is used for constructors (excluding parent classes) that are modified by public after taking a specified parameter type.

Once we have the constructor, we can use the newInstance() method to create instances of the class. In particular, if our constructor has no arguments, we can construct instances directly using class.newinstance ().

Get member method

package com.cunyu;

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;

/ * *

  • @author : cunyu
  • @version : 1.0
  • @className : Demo4
  • @date : 2021/4/8 13:51
  • @description: Member method fetch

* /

public class Demo4 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class personClass = Class.forName(“com.cunyu.Person”);

// Get all public member methods system.out.println (” Get all member methods “); Method[] methods = personClass.getMethods(); for (Method method : methods) { System.out.println(method); }

System.out.println(” get method with name “); Method getAgeMethod = personClass.getMethod(“getAge”); System.out.println(getAgeMethod);

Person Person = new Person(20, “village yuyuan “, 1312020, 3, 99.0f, 2); int age = (int) getAgeMethod.invoke(person); System.out.println(age);

}
Copy the code

}

Method[] getMethods()

Member methods (including the parent class) that are used to get all the public modifiers of the current class.

Method getMethod(String name, class <? >… parameterTypes)

Gets a member method (including the parent class) that is modified by a specified name public of the current class.

Method[] getDeclaredMethods()

Member methods used to get all the public modified member methods of the current class (excluding the parent class).

Method getDeclaredMethods(String name, class <? >… parameterTypes)

A member method (excluding the parent class) that gets one of the specified names public of the current class.

Once we have a member method of the class, if we want to execute a method, we can use the invoke() method to execute that method.

Get the name of the class

String getName()

GetName () : getName() : getName() : getName() : getName() : getName() : getName() : getName() : getName() : getName() : getName() : getName() : getName() : getName() : getName()

Reflection instance

Suppose we have a requirement that we can create objects of any class and execute its methods without changing the code of the class.

At this point, we can achieve this effect by using the configuration file + reflection, which is the basis of the framework we are using now. When we use reflection, we just need to modify the content of the configuration file to achieve the corresponding function without changing the code.

Suppose we have two classes, Student and Teacher, defined as follows;

To implement our requirements, the following steps are usually required:

1. The full class name of the object to be created and the method to be executed are configured in the configuration file.

Prop.properties, the main contents of which include the className and methodName properties, representing the full className of the class and the name of the method to be called, respectively. A concrete example is the following, representing a class named Student and a method named study.

2. Load and read the configuration file in the main method.

3. Use reflection technology to load the class into memory;

4. Then create an object using newInstance().

5. Finally, the invoke() method is used to execute the method;

Putting the whole process together is:

package com.cunyu;

import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties;

/ * *

  • @author : cunyu
  • @version : 1.0
  • @className : ReflectTest
  • @date : 2021/4/8 15:27
  • @ description: test

* /

public class ReflectTest { public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {// create config file object Properties = new Properties(); / / load the configuration file this this = ReflectTest. Class. GetClassLoader (); InputStream inputStream = classLoader.getResourceAsStream(“prop.properties”); properties.load(inputStream);

String className = properties.getProperty(“className”); // Get the data defined in the configuration file. String methodName = properties.getProperty(“methodName”);

Class name = class.forname (className);

Object = name.newinstance ();

Method Method = name.getMethod(methodName); method.invoke(object); }}

At this point, we just need to change the configuration in the prop.properties configuration file to output different results;

Well, this is the end of today’s article, I hope to help you confused in front of the screen