< 15 > Java reflection mechanism

1.1 understanding of reflection

Programs that can analyze class capabilities become reflective. Reflection is the key to being regarded as a dynamic language. The reflection mechanism allows programs to obtain the internal information of any class with the help of Reflection API during execution, and can directly operate the internal properties and methods of any object.

1.2 functions provided by 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

1.3 Class

  • Class loading process:
    After the program passes the javac.exe command, it will generate one or more bytecode files (. End of class).
    Then we use the java.exe command to interpret and run a bytecode file. It is equivalent to loading a bytecode file into memory. This process is called Class loading. The Class loaded into memory is called the runtime Class. This runtime Class is used as an instance of Class.
  • In other words, an instance of Class corresponds to a runtime Class.
  • Runtime classes loaded into memory will be cached for a certain period of time. Within this time, we can get this runtime class in different ways.

1.3.1 several ways to obtain Class instances


Method 1: call the attribute of the runtime class:. Class
Class clazz1 = Person.class;
Method 2: call the getClass() method in the Object class through the Object of the runtime class
Person p1 = new Person();
Class clazz2 = p1.getClass();
Method 3: call the static method of Class: forName(String classPath)
Class clazz3 = Class.forName("review01.Person");
What is put in parentheses is the position where the Person class exists;
Method 4: use class loader: ClassLoader (understand)

public class test01 {
    @Test
    public void test001() throws ClassNotFoundException {
        ClassLoader classLoader = test01.class.getClassLoader();
        classLoader.loadClass("review01.Person");
    }
}

1.4 use Classloader to load configuration files in src directory


-Method 1 for reading configuration files:
At this time, the file is under the current module by default

public class test01 {
    @Test
    public void test2() throws Exception {
        Properties pros =  new Properties();
        //At this time, the file is under the current module by default.
        //Method 1 for reading configuration files:
        FileInputStream fis = new FileInputStream("jdbc.properties");
        //FileInputStream fis = new FileInputStream("src\\jdbc.properties");
        pros.load(fis);
    }
}

-Method 2 for reading configuration files:
At this time, the configuration file is under src of the current module by default

public class test01 {
    @Test
    public void test2() throws Exception {
        Properties pros =  new Properties();
        //The second way to read the configuration file is to use ClassLoader
        //The default identification of the configuration file is: under src of the current module
        ClassLoader classLoader = test01.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("jdbc.properties");
        pros.load(is);
    }
}

1.5 reflection application 1: create objects of runtime classes

public class test01 {
    @Test
    public void test2() throws Exception {

        Class<Person> clazz = Person.class;
        Person obj = clazz.newInstance();
       
    }
}

Note:
newInstance(): call this method to create the object of the corresponding runtime class. Constructor that internally calls an empty parameter of the runtime class.
To create the object of the runtime class normally with this method, you need to:
1. The runtime class must provide a constructor with null parameters
2. The constructor of null parameter has sufficient access rights. Normally, it is set to public.

A public null parameter constructor is required in the javabean. reason:
1. It is convenient to create objects of runtime classes through reflection
2. When a subclass inherits this runtime class, it is ensured that the parent class is the constructor when super() is called by default

1.6 reflection application 2: obtain the complete structure of the runtime class

Through reflection, we can obtain all properties, methods, constructors, parent classes, interfaces, packages, annotations, exceptions, etc. in the corresponding runtime class...

  • Get attribute structure
    getField(String name): or take the named attribute in the current runtime class and its parent class
    getFields(): get the attributes declared as public access rights in the current runtime class and its parent class
    Getdeclaraedfield(): get the named attribute in the current runtime class
    Getdeclaraedfields(): get all the properties declared in the current runtime class. (excluding properties declared in the parent class)

  • Acquisition method
    getMethods(): get the method declared as public permission in the current runtime class and its parent class
    Getdeclaraedmethods(): get all the methods declared in the current runtime class. (excluding methods declared in the parent class)

  • Get constructor structure
    getConstructors(): get the constructor declared as public in the current runtime class
    Getdeclaraedconstructors(): get all constructors declared in the current runtime class

  • Gets the parent class of the runtime class
    getSuperclass()

  • Gets the interface implemented by the runtime class
    getInterfaces()

  • Gets the package where the runtime class is located
    getPackage()

  • Gets the annotation of the runtime class declaration
    getAnnotations()

1.6 reflection application 3: call the specified structure of the runtime class

  • ① Call the specified property:
@Test
public void testField() throws Exception {
    Class clazz = Person.class;

    //Create an object for the runtime class
    Person p = (Person) clazz.newInstance();

    //1. Getdeclaraedfield (string fieldname): get the attribute of the specified variable name in the runtime class
    Field name = clazz.getDeclaredField("name");

    //2. Ensure that the current attribute is accessible
    name.setAccessible(true);
    
    //3. Get and set the property value of the specified object
    name.set(p,"Tom");//void set(Object obj,Object newValue) sets the Field described by this Field object in the Obj object to a new value newValue

    System.out.println(name.get(p));
}
  • ② Call the specified method:
@Test
    public void testMethod() throws Exception {
        Class clazz = Person.class;
        //Create an object for the runtime class
        Person p = (Person) clazz.newInstance();
        /*
        1.Gets a specified method
        getDeclaredMethod():Parameter 1: indicates the name of the obtained method parameter 2: indicates the formal parameter list of the obtained method
         */
        Method show = clazz.getDeclaredMethod("show", String.class);
        //2. Ensure that the current method is accessible
        show.setAccessible(true);
        /*
        3. invoke() of calling method: parameter 1: caller of method parameter 2: argument assigned to method parameter
        invoke()The return value is the return value of the method called in the corresponding class.
         */
        Object returnValue = show.invoke(p,"CHN"); //String nation = p.show("CHN");
        System.out.println(returnValue);
    }

Note:
public Object invoke(Object implicitParameter,Object[] explicitParameters)
Call the method described by this object, pass in the given parameter, and return the return value of the method.
For static methods, null is passed in as an implicit parameter.

  • ③ Call the specified constructor:
@Test
public void testConstructor() throws Exception {
    Class clazz = Person.class;
    /*
    1.Gets the specified constructor
    getDeclaredConstructor():Parameters: indicates the list of parameters for the constructor
     */
    Constructor constructor = clazz.getDeclaredConstructor(String.class);
    //2. Ensure that this constructor is accessible
    constructor.setAccessible(true);
    //3. Call this constructor to create the object of the runtime class
    Person per = (Person) constructor.newInstance("Tom");
}

Article reference:

b station: Java teaching video of song Hongkang, a teacher from Silicon Valley;
Java core technology Volume I

Keywords: Java

Added by amorphous on Fri, 24 Sep 2021 17:02:02 +0300