Reflection mechanism (field, method, constructor)

Posted by accident on Fri, 28 Jan 2022 06:48:49 +0100

 

catalogue

1, Overview of reflection mechanism

1. What is the reflection mechanism? What's the use of reflection mechanism?

2. What are the important classes related to reflection mechanism?

2, Three ways to get Class in java

1,Class c = Class.forName("full class name");

2. Class c = object getClass();

3. Any data type (including basic data types) has a "static" class attribute

4. The class es obtained by the three methods are the same

3, Instantiate objects through reflection mechanism

1. Use the newInstance() method of the Class object to create an instance of the Class corresponding to the Class object.

2. Obtain the specified Constructor object through the Class object, and then call the newInstance() method of the Constructor object to create an instance. This method can construct an instance of a Class with a specified Constructor.

4, When loading a class, the static code block is executed only once

5, Research path

1. Get the path through io stream: FileReader reader=new FileReader("file path")

2,Thread.currentThread().getContextClassLoader().getResource("start from the root path of the class (add the suffix of the file)") getPath()

3,ResourceBundle.getBundle("start from the root path of the class (without the suffix properties of the file)")

6, filed

1. Get filed

2. Set the value of field

7, method

1. Get method

2. Call method

3. Code demonstration

8, Constructor

1. Get Constructor (construction method)

2. Call Constructor (construction method)

3. Code demonstration

9, Get parent class and parent class interface

1, Overview of reflection mechanism

1. What is the reflection mechanism? What's the use of reflection mechanism?

Reflection mechanism: bytecode files can be operated through the reflection mechanism in java language. (bytecode files can be read and modified.)
Code fragments can be manipulated through reflection mechanism. (class file.)
Function: it can make the program more flexible.

Purpose:

1. Decompile: class-->. java

2. Access the properties, methods and construction methods of java objects through reflection mechanism

3. When we are using IDE, such as Ecplise, when we input an object or class and want to call its properties and methods, the compiler will automatically list its properties or methods as soon as we press the dot. Here is reflection.

4. The most important use of reflection is to develop various common frameworks. For example, many frameworks (Spring) are configured (such as configuring beans through XML files). In order to ensure the universality of the framework, they may need to load different classes or objects and call different methods according to the configuration file. At this time, reflection must be used to dynamically load the loaded objects at runtime.
 

Note: the relevant classes of reflection mechanism are in Java lang.reflect.* Bao Xia

2. What are the important classes related to reflection mechanism?

java.lang.Class: represents the whole bytecode, one type and the whole class.

java.lang.reflect.Method: represents the method bytecode in bytecode. Represents a method in a class.  

java.lang.reflect.Constructor: represents the construction method in bytecode. Construction methods in representative classes

java.lang.reflect.Field: represents the attribute bytecode in bytecode. Represents the member variables in the class (static variables + instance variables).

        java.lang.Class:
            public class User{
                // Field
                int no;

                // Constructor
                public User(){
                }
                public User(int no){
                    this.no = no;
                }

                // Method
                public void setNo(int no){
                    this.no = no;
                }
                public int getNo(){
                    return no;

2, Three ways to get Class in java

1,Class c = Class.forName("full class name");

A static method in Class: public static forName();

be careful:

         1. It is a static method

         2. The argument to the method is a string

         3. String requires a full class name

         4. The full class name must contain the package name

[code display]

package com.bjpowernode.java.reflect;
public class ReflectTest01{ 
    public static void main(String[] args){
           try{
                 Class c1=Class.forName("java.lang.String");//c1 represents String under lang package Class file, or c1 represents String type
                Class c2=Class.forName("java.util.Date");//c2 stands for Date type
             }catch(ClassNotFoundException e){
                 e.printStackTrace();
                }
         }
}

2. Class c = object getClass();

getClass() is an implemented method in the Object class

[code display]

//For example, String class
String  str = mew String();
Class c =str.getClass();

 

3. Any data type (including basic data types) has a "static" class attribute

[code display]

//For example, String class
Class c = String.class

 

4. The class es obtained by the three methods are the same

[code demonstration]

public class Fanshe {
	public static void main(String[] args) {
         //The first way is to get the Class object
		try {
			Class stuClass1 = Class.forName("fanshe.Student");//Note that this string must be the real path, that is, the class path with package name and package name Class name
			System.out.println(stuClass1.getName());//Get Class object
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//The second way is to get the Class object  
		Student stu1 = new Student();//This new generates a Student object and a Class object.
		Class stuClass2 = stu1.getClass();
		System.out.println(stuClass2==stuClass1);//Judge whether the two methods obtain the same Class object
		
		//The third way is to get the Class object
		Class stuClass3 = Student.class;
		System.out.println(stuClass3 == stuClass2);//Judge whether the Class object obtained by the first method and the Class object obtained by the second method are the same
		
		
		
	}
}

Note that during operation, only one Class object is generated for a Class, so the print result is true;

Among the three methods, the first one is often used. The second one is what you need to reflect when you have all the objects. The third one needs to import the class package. If the dependency is too strong, you will throw a compilation error without importing the package. Generally, the first method is used. A string can be passed in or written in the configuration file.

3, Instantiate objects through reflection mechanism

1. Use the newInstance() method of the Class object to create an instance of the Class corresponding to the Class object.

Compared with new, the advantage of an object is that it is more flexible

class c=Class.forName("path")

Object obj=c.newInstance() / / instantiate the object by calling the parameterless constructor through newInstance()

be careful:

The underlying call of newInstance() is the parameterless construction method of this type

There must be a parameterless constructor (so the new class must override the parameterless constructor in case the parameterless constructor cannot be used after overriding the parameterless constructor). If there is no parameterless constructor, an instantiation exception will occur

Contents of properties file: classname = "full path of class"

2. Obtain the specified Constructor object through the Class object, and then call the newInstance() method of the Constructor object to create an instance. This method can construct an instance of a Class with a specified Constructor.

//Get the Class object corresponding to a Class

Class c=Class.forName("route");

//Gets the constructor of the class with a String parameter and an int parameter

Constructor con1 = c.getDeclaredConstructor(String.class,int.class);

//Create instance from constructor

Object obj1 = con1.newInstance("abc",2);

System.out.println(obj1);



//Gets the class's parameterless constructor

Constructor con2 = c.getDeclaredConstructor();

//Create instance from constructor

Object obj2= con2.newInstance();

System.out.println(obj2);

 

4, When loading a class, the static code block is executed only once

Class. The execution of the method forname ("full class name") will lead to class loading. When the class is loaded, the static code block will be executed only once.  

package com.bjpowernode.java.reflect;

public class MyClass{
       //Static code blocks are executed when the class is loaded and only once.
       static {
          System.out.println("MyClass Class static code block execution!");
      }
}
package com.bjpowernode.java.reflect;
/*
Study class What happened to forname()?
     If you only want the static code block of one class to execute, the rest of the code will not execute
     You can use:
         Class.forName("Full class name ")
         The execution of this method will lead to class loading. When the class is loaded, the static code block will be executed
*/

public class ReflectTest01{ 
    public static void main(String[] args){
           try{
                 Class.forName("com.bjpowernode.java.reflect.MyClass");                
             }catch(ClassNotFoundException e){
                 e.printStackTrace();
                }
         }
}

5, Research path

1. Get the path through io stream: FileReader reader=new FileReader("file path")

The disadvantage of this method is poor portability. Once the code leaves idea or eclipse, the current path may not be the root of the project. At this time, the path obtained in the code is invalid.

2,Thread.currentThread().getContextClassLoader().getResource("start from the root path of the class (add the suffix of the file)") getPath()

This method can directly obtain the absolute path of the file

For example: 1 Place a classinfo2.0 in src Properties file

           2. Place a DB in the src\com\bjpowernode\java\bean path Properties file

[code demonstration]

3,ResourceBundle.getBundle("start from the root path of the class (without the suffix properties of the file)")

This method can quickly bind attribute resource files

be careful:

      1. The path of this file must be under the classpath

      2. The suffix of this file must be properties

[code demonstration]

6, filed

1. Get filed

There are several methods to obtain the member variable set of a Class object:

1. getFields(): get all "public fields"

public Field[] getFields()

2. getDeclaredFields(): get all fields, including private, protected, default and public; But you cannot get the member variable of its parent class.

public Field[] getDeclaredFields()

3. getField(String fieldName): get a "public" field;

public Field getField(String fieldName)

4. getDeclaredField(String fieldName): get a field (which can be private)

public Field getDeclaredField(String fieldName)

Getting private properties and setting values need to break the encapsulation

Class f=Class.getforName("route") //Gets the class of the class
Object obj=f.newInstance() //Create object obj of class
Field fieldname = stuClass.getDeclaredField("name"); //Get private property name
fieldname.setAccessible(true);//Breaking the encapsulation, external can also access private properties
fieldname.set(obj, "1888");//Assign a value to the attribute name of object obj
System.out.println(fieldname.get(obj));	//Gets the value of the name attribute of the obj object

2. Set the value of field

Field --> public void set(Object obj,Object value):

Parameter Description:
                     1.obj: the object of the field to be set;
                     2.value: the value to be set for the field;

Steps:
1,Gets the name of the class class
Class s=Class.forName("Classpath")
2,Create an object
Object obj=s.newInstance()
3,Get variable
Field fieldname=s.getDeclaredField("Variable name")
4,set variable
fieldname.setAccessible(true);//If the property is private, you need to break the encapsulation
fieldname.set(obj,value)

[code demonstration]

Student class:

package fanshe.field;
 
public class Student {
	public Student(){
		
	}
	//**********Field*************//
	public String name;
	protected int age;
	char sex;
	private String phoneNum;
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", sex=" + sex
				+ ", phoneNum=" + phoneNum + "]";
	}

}

Test class:

package fanshe.field;
import java.lang.reflect.Field;

public class Fields { 
		public static void main(String[] args) throws Exception {
			//1. Get Class object
			Class stuClass = Class.forName("fanshe.field.Student");
			//2. Get field
			System.out.println("************Get all public fields********************");
			Field[] fieldArray = stuClass.getFields();
			for(Field f : fieldArray){
				System.out.println(f);
			}
			System.out.println("*********Get all fields(Including private, protected, default)********");
			fieldArray = stuClass.getDeclaredFields();
			for(Field f : fieldArray){
				System.out.println(f);
			}
			System.out.println("*************Get public field**And call*********************");
			Field f = stuClass.getField("name");
			System.out.println(f);
			//Get an object
			Object obj = stuClass.newInstance();//Generate Student object -- "Student stu = new Student();
			//Set values for fields
			f.set(obj, "Lau Andy");//Assign a value to the name attribute in the Student object -- "stu Name = "Andy Lau"
			
			System.out.println("full name:" + f.get(obj));
			
			
			System.out.println("**************Get private field****And call*******************");
			Field p = stuClass.getDeclaredField("phoneNum");
			System.out.println(p);
			p.setAccessible(true);//Violent reflex, lifting private restrictions
			p.set(obj, "18888889999");
			System.out.println(p.get(obj));			
		}
}

7, method

Understanding: variable length parameters:

//Variable length parameter eg: "int...args"
/*
1.The number of variable length parameters can be 0~N
2.Variable length parameters can only have one at most in the parameter list and are placed in the last position
3.The variable parameter length can be viewed as an array
*/


public class Test { 
		public static void main(String[] args) {
           m1();
           m1(10);
           m1(10,20,40);
         //m1(10."abc") / / parameters can only be int types defined in m1 method

           m2(10,"a","b","I");
           m3("I","happiness","Joyous","you")



public static void m1(int...args){
         system.out.println("m1 Method executed");
}

//public static void m2(int...args1;String...args2){  
    //This method does not work because there can only be one variable length parameter in a method, which is placed last
//        system.out.println("m2 method executed");
//}

public static void m2(int a;String...args1){
    system.out.println("m2 Method executed")p;
}

public static void m3(String...args){
//Args has a length attribute, indicating that args is an array
//The variable parameter length can be viewed as an array
for(int i;i<args.length;i++){
  system.out.println(args[i]);
}


}
}

1. Get method

Note: how does java distinguish a method? Can you just rely on the method name? Obviously not, because of the overload mechanism in java, the same class may contain multiple methods with the same method name. So we distinguish a method by method name + parameter list.

There are mainly the following methods to obtain the method set of a Class object:

1. getDeclaredMethods() method gets all member methods, including private ones (excluding inherited ones)

public Method[] getDeclaredMethods() throws SecurityException

2. getMethods() method obtains all "public methods"; (methods that contain the parent class also contain the Object class)

public Method[] getMethods() throws SecurityException

3. The getMethod() method returns a specific method, in which the first parameter is the method name, and the following parameter is the object of the Class corresponding to the parameter of the method (0 or more).

For example:

public Method getMethod(String name, Class<?>... parameterTypes)

2. Call method

Field --> public void invoke(Object obj,Object value):

Parameter Description:
                     1.obj: the object of the method to be called;
                     2.value: argument;

Steps:
1. Gets the class of the class
Class s=Class.forName("classpath")
2. Create an object
Object obj=s.newInstance()
3. Get variable
Method methodname=s.getDeclaredMethod("variable name", the parameter of the method corresponds to the object of Class)
4. Set variables
methodname.setAccessible(true);// If the property is private, you need to break the encapsulation
methodname.invoke(obj,value)

3. Code demonstration

student class:

package fanshe.method;
 
public class Student {
	//**************Member method***************//
	public void show1(String s){
		System.out.println("Called: public, String Parametric show1(): s = " + s);
	}
	protected void show2(){
		System.out.println("Called: protected, parameterless show2()");
	}
	void show3(){
		System.out.println("Called: default, parameterless show3()");
	}
	private String show4(int age){
		System.out.println("Called, private, and has a return value, int Parametric show4(): age = " + age);
		return "abcd";
	}
}

Test class:

import java.lang.reflect.Method;
public class MethodClass {
 	public static void main(String[] args) throws Exception {
		//1. Get Class object
		Class stuClass = Class.forName("fanshe.method.Student");
		//2. Get all public methods
		System.out.println("***************Get all "public" methods*******************");
		stuClass.getMethods();
		Method[] methodArray = stuClass.getMethods();
		for(Method m : methodArray){
			System.out.println(m);
		}
		System.out.println("***************Get all methods, including private ones*******************");
		methodArray = stuClass.getDeclaredMethods();
		for(Method m : methodArray){
			System.out.println(m);
		}
		System.out.println("***************Get public show1()method*******************");
		Method m = stuClass.getMethod("show1", String.class);
		System.out.println(m);
		//Instantiate a Student object
		Object obj = stuClass.getConstructor().newInstance();
		m.invoke(obj, "Lau Andy");
		
		System.out.println("***************Get private show4()method******************");
		m = stuClass.getDeclaredMethod("show4", int.class);
		System.out.println(m);
		m.setAccessible(true);//Lifting private restrictions
		Object result = m.invoke(obj, 20);//Two parameters are required, one is the object to be called (with reflection obtained) and the other is the argument
		System.out.println("Return value:" + result);	
	}
}

Operation results:

***************Get all "public" methods*******************
public void fanshe.method.Student.show1(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
***************Get all methods, including private ones*******************
public void fanshe.method.Student.show1(java.lang.String)
private java.lang.String fanshe.method.Student.show4(int)
protected void fanshe.method.Student.show2()
void fanshe.method.Student.show3()
***************Get public show1()method*******************
public void fanshe.method.Student.show1(java.lang.String)
Called: public, String Parametric show1(): s = Lau Andy
***************Get private show4()method******************
private java.lang.String fanshe.method.Student.show4(int)
Called, private, and has a return value, int Parametric show4(): age = 20
 Return value: abcd
 

8, Constructor

1. Get Constructor (construction method)

Note: how to distinguish construction methods in java? All construction methods need to have the same method name as the class according to the parameter type.

The Class object can be used to obtain: construction method, member variable and member method in a Class; And visit members;

1. The getConstructors() method can get all "public" construction methods

public Constructor[] getConstructors()

2. getDeclaredConstructors() method obtains all construction methods (including private, protected, default and public)

public Constructor[] getDeclaredConstructors()

3. The getConstructor() method gets a single "public" constructor

public Constructor getConstructor(Class... parameterTypes)

4. getDeclaredConstructor() method obtains that "a constructor" can be private, protected, default or public;

public Constructor getDeclaredConstructor(Class... parameterTypes)

2. Call Constructor (construction method)

     Constructor-->newInstance(Object... initargs)

3. Code demonstration

Student class: there are six construction methods in total

package fanshe;
public class Student {
	//---------------Construction method-------------------
	//(default construction method)
	Student(String str){
		System.out.println("(default)Construction method of s = " + str);
	}
	//Nonparametric construction method
	public Student(){
		System.out.println("The public and parameterless construction method is called to execute...");
	}
	//Construction method with one parameter
	public Student(char name){
		System.out.println("full name:" + name);
	}
	//Construction method with multiple parameters
	public Student(String name ,int age){
		System.out.println("full name:"+name+"Age:"+ age);//There is a problem with the implementation efficiency of this, which will be solved later.
	}
	//Protected construction method
	protected Student(boolean n){
		System.out.println("Protected construction method n = " + n);
	}
	//Private construction method
	private Student(int age){
		System.out.println("Private construction method age:"+ age);
	}
}

Test class:

package fanshe;
import java.lang.reflect.Constructor;

public class Constructors {
 	public static void main(String[] args) throws Exception {
		//1. Load Class object
		Class clazz = Class.forName("fanshe.Student");
		
		//2. Get all public construction methods
		System.out.println("**********************All public construction methods******************");
		Constructor[] conArray = clazz.getConstructors();
		for(Constructor c : conArray){
			System.out.println(c);
		}
		
		System.out.println("******All construction methods(Including: private, protected, default, public)********");
		conArray = clazz.getDeclaredConstructors();
		for(Constructor c : conArray){
			System.out.println(c);
		}
		
		System.out.println("*****************Get public and parameterless construction methods******************");
		Constructor con = clazz.getConstructor(null);
		//1> . because it is a parameterless construction method, the type is null and can be written without writing: what is needed here is the type of a parameter. Remember that it is the type
		//2> The class object that describes the parameterless constructor is returned.
		System.out.println("con = " + con);
 
		//Call construction method
		Object obj = con.newInstance();
	//	System.out.println("obj = " + obj);
	//	Student stu = (Student)obj;
		
		System.out.println("******************Get the private constructor and call******************");
		con = clazz.getDeclaredConstructor(char.class);
		System.out.println(con);
		//Call construction method
		con.setAccessible(true);//Brute force access (ignore access modifier)
		obj = con.newInstance('male');
	}
}

Operation results:

**********************All public constructors*********************************
public fanshe.Student(java.lang.String,int)
public fanshe.Student(char)
public fanshe.Student()
************All construction methods(Including: private, protected, default, public)***************
private fanshe.Student(int)
protected fanshe.Student(boolean)
public fanshe.Student(java.lang.String,int)
public fanshe.Student(char)
public fanshe.Student()
fanshe.Student(java.lang.String)
*****************Get public and parameterless construction methods*******************************
con = public fanshe.Student()
The public and parameterless construction method is called to execute...
******************Get the private constructor and call*******************************
public fanshe.Student(char)
Name: Male

 

 

9, Get parent class and parent class interface

Result display:

 

Reference article:

Original link: https://blog.csdn.net/a745233700/article/details/82893076

                  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Topics: Java Class reflection