Reflection of [JavaSE basic review] (including practice Demo)

Keywords: Java bootstrap JavaSE jar

reflex

1. Class loader

1.1 loading of class

When a program wants to use a class, if the class has not been loaded into memory, the system will initialize the class through three steps: loading, connecting and initialization.

  • load

    This is to read the class file into memory and create a class object for it.

    When any Class is used, the system will create a Class object

  • connect

    Verify whether there is a correct internal structure and is consistent with other classes

    Preparation is responsible for allocating memory for static members of the class and setting default initialization values

  • Parsing replaces the symbolic reference in the binary data of the class with a direct reference

  • initialization

    This is the initialization step we talked about before

1.2 initialization timing

  1. Create an instance of a class

  2. Class, or assign a value to a static variable

  3. Class

  4. Use reflection to force the creation of java.lang.Class objects corresponding to a class or interface

  5. Initializes a subclass of a class

  6. Directly use the java.exe command to run a main class

Class 1.3 loader

It is responsible for loading the. Class file into the internal and generating the corresponding class object for it.

Although we don't need to care about the class loading mechanism, we can better understand the operation of the program by understanding this mechanism

Composition of class 1.4 loader

Bootstrap ClassLoader root classloader

Also known as boot class loader, it is responsible for loading Java core classes

For example, System,String, etc. In the JDK, in the rt.jar file under the lib directory of JRE

Extension ClassLoader extension classloader

Be responsible for loading jar packages in JRE's extension directory.

In the JDK, the ext directory is under the lib directory of JRE

System ClassLoader

It is responsible for loading the class file from the java command and the jar package and classpath specified by the classpath environment variable when the JVM starts.

Through these descriptions, we can know who loads the commonly used classes.

So far, we know how to load class files into memory. If we only stand on the perspective of these class files, how can we use the contents of these class files? This is what we want to study.

2. Reflection mechanism

java reflection mechanism is to know all the properties and methods of any class in the running state; For any object, you can call any of its methods and properties; This kind of dynamically acquired information and the function of dynamically calling object methods are called the reflection mechanism of java language.

To dissect a Class, you must first obtain the bytecode file object of the Class. The anatomy uses the methods in the Class class, so we must first obtain the Class type object corresponding to each bytecode file.

2.1 Class

After reading the Class class of API, we know that Class has no public constructor. The Class object is automatically constructed by the Java virtual machine and by calling the defineClass method in the Class loader when the Class is loaded

l three ways to obtain Class objects

Method 1: use the getObject() method in the Object class

Person p = new Person();

Class c = p.getClass();

Method 2: obtain the bytecode file object through the class name. Class (any data type has a class static attribute, which looks simpler than the first method).

Class c2 = Person.class;

Method 3: through the method in Class (just pass the Class name as a string to the static method forName in Class).

Class c3 = Class.forName("Person");

l note: the difference between the third and the first two

In the first two, you must specify the Person type

This extension is stronger. I don't need to know your class. I only provide strings and load them according to the configuration file

/*
 * How to get the. class bytecode file object
 * 		1: Through the getObject() method in the Object class
 * 		2: Get bytecode file object through class name. Class
 * 		3: Methods in reflection,
 * 			public static Class<?> forName(String className) throws ClassNotFoundException
 * 			Returns the Class object associated with the Class or interface with the given string name 
 */
public class ReflectDemo {
	public static void main(String[] args) throws ClassNotFoundException {
		// 1: Through the getObject() method in the Object class
		// Person p1 = new Person();
		// Class c1 = p1.getClass();
		// System.out.println("c1 = "+ c1);

		// 2: Get bytecode file object through class name. Class
		// Class c2 = Person.class;
		// System.out.println("c2 = "+ c2);

		// 3: Methods in reflection
		Class c3 = Class.forName("cn.itcast_01_Reflect.Person");// Package name. Class name
		System.out.println("c3 = " + c3);
	}
}
	Person class
package cn.itcast_01_Reflect;
public class Person {
	//Member variable
	public String name;
	public int age;
	private String address;

	//Construction method
	public Person() {
		System.out.println("Null parameter construction method");
	}
	
	public Person(String name) {
		this.name = name;
		System.out.println("have String Construction method of");
	}
	//Private construction method
	private Person(String name, int age){
		this.name = name;
		this.age = age;
		System.out.println("have String,int Construction method of");
	}
	
	public Person(String name, int age, String address){
		this.name = name;
		this.age = age;
		this.address = address;
		System.out.println("have String, int, String Construction method of");
	}
	
	//Member method
	//Method with no return value and no parameters
	public void method1(){
		System.out.println("Method with no return value and no parameters");
	}
	//Method with no return value and parameters
	public void method2(String name){
		System.out.println("Method with no return value and parameters name= "+ name);
	}
	//There are return values and no parameters
	public int method3(){
		System.out.println("Method with return value and no parameters");
		return 123;
	}
	//Methods with return values and parameters
	public String method4(String name){
		System.out.println("Methods with return values and parameters");
		return "ha-ha" + name;
	}
	//Private method
	private void method5(){
		System.out.println("Private method");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";
	}
}

2.2 obtain the construction method by reflection and use it

In the reflection mechanism, the members in the Class (Constructor, member method and member variable) are encapsulated into corresponding classes for representation. The construction method is represented by the Class Constructor. The construction method can be obtained through the method provided in Class:

  • Returns a constructor
    Public constructor getconstructor (class <? >... parameterTypes) gets the public modifier and specifies the construction method corresponding to the parameter type

    Public constructor getdeclaraedconstructor (class <? >... parameterTypes) gets the constructor (including private) corresponding to the specified parameter type

  • Returns multiple constructor methods

    public Constructor<?> [] getconstructors() get the constructor of all public modifiers

    public Constructor<?> [] getdeclaraedconstructors() get all construction methods (including private ones)

    public class ReflectDemo {
    	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
    		//Get Class object
    		Class c = Class.forName("cn.itcast_01_Reflect.Person");//Package name. Class name
    		
    		//Get all construction methods
    		//Constructor[] cons = c.getConstructors();
    		Constructor[] cons = c.getDeclaredConstructors();
    		for (Constructor con : cons) {
    			System.out.println(con);
    		}
    		
    		System.out.println("------------------------");
    		//Get a constructor
    		//public Person() 
    		Constructor con1 = c.getConstructor(null);
    		System.out.println(con1);
    		
    		//public Person(String name)
    		Constructor con2 = c.getConstructor(String.class);
    		System.out.println(con2);
    		
    		//private Person(String name, int age)
    		Constructor con3 = c.getDeclaredConstructor(String.class, int.class);
    		System.out.println(con3);
    		
    		//public Person(String name, int age, String address)
    		Constructor con4 = c.getDeclaredConstructor(String.class, int.class, String.class);
    		System.out.println(con4);
    	}
    }
    

    2.3 obtain the construction method and create objects through reflection

    To obtain the construction method, the steps are as follows:

    1. Get Class object

    2. Gets the specified construction method

    3. Create objects by constructing methods in the method class Constructor

    public T newInstance(Object... initargs)

    Code demonstration

public class ConstructorDemo {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//1. Get Class object
		Class c = Class.forName("cn.itcast_01_Reflect.Person");//Package name. Class name
		//2. Obtain the specified construction method
		//public Person()
		//Constructor con = c.getConstructor(null);
		
		//public Person(String name, int age, String address)
		Constructor con = c.getConstructor(String.class, int.class, String.class);
		
		//3. Create an object by constructing the Constructor method in the method class
		//Object obj = con.newInstance(null);
		Object obj = con.newInstance("Xiao Ming", 22, "Harbin");
		
		//display
		System.out.println(obj);
	}
}

2.3 obtain private construction methods and create objects through reflection

The AccessibleObject class is the parent class of Field, Method, and Constructor objects. It provides the ability to mark reflected objects to cancel the default Java language access control check when used.

For public members, default (packaged) access members, protected members and private members, access checks are performed when Field, Method or Constructor objects are used to set or obtain fields, call methods, or create and initialize new instances of classes, respectively. Common methods are as follows:

public void setAccessible(boolean flag) throws SecurityException

If the parameter value is true, it indicates that the Java language access check should be cancelled when the reflected object is used. If the parameter value is false, it indicates that the reflected object should implement Java language access check.

To obtain the private construction method, the steps are as follows:

  1. Get Class object

  2. Gets the specified construction method

  3. Violent access through setAccessible(boolean flag) method

  4. Create objects by constructing methods in the method class Constructor

public T newInstance(Object... initargs)

public class ConstructorDemo2 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//1. Get Class object
		Class c = Class.forName("cn.itcast_01_Reflect.Person");//Package name. Class name
		
		//2. Obtain the specified construction method
		//private Person(String name, int age)
		Constructor con = c.getDeclaredConstructor(String.class, int.class);
		
		//3. Violent reflex 
		con.setAccessible(true);//Cancel Java language access check
		
		//4. Create objects by constructing the functions in the method class
		Object obj = con.newInstance("Xiao Ming", 23);
		System.out.println(obj);
		
	}
}

2.4 get member variables through reflection and use

In the reflection mechanism, the member variables in the Class are represented by the Class Field. Member variables can be obtained through the methods provided in Class:

Returns a member variable

public Field getField(String name) gets the specified public modified variable

Public field getdeclaraedfield (string name) gets any specified variable

Returns multiple member variables

public Field[] getFields() gets all public modified variables

Public field [] getdeclaraedfields() get all variables (including private)

public class FieldDemo {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
		//Get Class object
		Class c = Class.forName("cn.itcast_01_Reflect.Person");
		
		//Get member variable
		//Multiple variables
		//Field[] fields = c.getFields();
		Field[] fields =  c.getDeclaredFields();
		for (Field field : fields) {
			System.out.println(field);
		}
		System.out.println("-----------------");
		//A variable
		//public int age;
		Field ageField = c.getField("age");
		System.out.println(ageField);
		
		//private String address
		Field addressField = c.getDeclaredField("address");
		System.out.println(addressField);
	}
}

2.5 create objects through reflection, obtain specified member variables, and perform assignment and value acquisition operations

To obtain the member variable, the steps are as follows:

  1. Get Class object

  2. Get construction method

  3. Create objects through construction methods

  4. Get the specified member variable (private member variable, accessed through setAccessible(boolean flag) method)

  5. Assign a value or get a value to the specified member variable of the specified object through the method

public void set(Object obj, Object value)

In the specified object obj, set the member variable represented by this Field object to the specified new value

public Object get(Object obj)

Returns the value of the member variable represented by this Field object in the specified object obj

public class FieldDemo2 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
		//1. Get Class object
		Class c = Class.forName("cn.itcast_01_Reflect.Person");
		//2. Obtain the construction method
		//public Person(String name) 
		Constructor con = c.getConstructor(String.class);
		//3. Create objects through construction methods
		Object obj = con.newInstance("Xiao Ming");
		//4. Get the specified member variable
		//public String name;
		Field nameField = c.getField("name");
		//public int age;
		Field ageField = c.getField("age");
		//private String address;
		Field addressField = c.getDeclaredField("address");
		addressField.setAccessible(true); //Cancel Java language access check
		
		//5. Assign a value or obtain a value to the specified member variable of the specified object through the method
		System.out.println("name = "+ nameField.get(obj));
		System.out.println("age = "+ ageField.get(obj));
		System.out.println("address = "+ addressField.get(obj));
		
		//assignment
		ageField.set(obj, 23);
		addressField.set(obj, "Kelly square");
		
		System.out.println("------------------------");
		System.out.println("name = "+ nameField.get(obj));
		System.out.println("age = "+ ageField.get(obj));
		System.out.println("address = "+ addressField.get(obj));
	}
}

2.6 get member method through reflection and use

In the reflection mechanism, the member methods in the Class are represented by Class Method. Member methods can be obtained through the methods provided in Class:

Return to get a method:

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

Method to get public modifier

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

Get any method, including private

Parameter 1: name: name of the method to find; Parameter 2: parameterTypes the parameter type of the method

Return to get multiple methods:

public Method[] getMethods() gets the methods of all public modifications in this class and its parent class

public Method[] getDeclaredMethods() gets all the methods in this class (including private ones)

public class MethodDemo {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
		//Get Class object
		Class c = Class.forName("cn.itcast_01_Reflect.Person");
		
		//Get multiple methods
		//Method[] methods = c.getMethods();
		Method[] methods = c.getDeclaredMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
		
		System.out.println("-----------------------");
		//Get a method:
		//public void method1()
		Method method = c.getMethod("method1", null);
		System.out.println(method);
		//public String method4(String name){
		method = c.getMethod("method4", String.class);
		System.out.println(method);
		//Private method
		//private void method5()
		method = c.getDeclaredMethod("method5", null);
		System.out.println(method);
	}
}

2.7 create objects and call specified methods through reflection

To obtain the member method, the steps are as follows:

  1. Get Class object

  2. Get construction method

  3. Create objects through construction methods

  4. Gets the specified method

  5. Execute the method found

public Object invoke(Object obj, Object... args)

Execute the Method represented by the current Method object in the specified object obj, and the parameters to be passed in by the Method are specified through args.

Code demonstration:

public class MethodDemo2 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//1. Get Class object
		Class c = Class.forName("cn.itcast_01_Reflect.Person");
		//2. Obtain the construction method
		//public Person(String name, int age, String address){
		Constructor con = c.getConstructor(String.class, int.class, String.class);
		//3. Create objects through construction methods
		Object obj = con.newInstance("Xiao Ming", 23, "Harbin");
		//4. Get the specified method
		//public void method1() has no method with return value and no parameters
		//Method m1 = c.getMethod("method1", null);
		
		//public String method4(String name)
		Method m4 = c.getMethod("method4", String.class);
		
		//5. Execute the method found
		//m1.invoke(obj, null);
		
		Object result = m4.invoke(obj, "itcast");
		System.out.println("result = " + result);
	}
}

2.8 create an object through reflection and call the specified private method

To obtain the private member method, the steps are as follows:

  1. Get Class object

  2. Get construction method

  3. Create objects through construction methods

  4. Gets the specified method

  5. Open violent access

  6. Execute the method found

public Object invoke(Object obj, Object... args)

Execute the Method represented by the current Method object in the specified object obj, and the parameters to be passed in by the Method are specified through args.

Code demonstration:

public class MethodDemo3 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//1. Get Class object
		Class c = Class.forName("cn.itcast_01_Reflect.Person");
		//2. Obtain the construction method
		//public Person(String name, int age, String address){
		Constructor con = c.getConstructor(String.class, int.class, String.class);
		//3. Create objects through construction methods
		Object obj = con.newInstance("Xiao Ming", 23, "Harbin");
		//4. Get the specified method
		//private void method5(){
		Method m5 = c.getDeclaredMethod("method5", null);
		//5. Open violent visit
		m5.setAccessible(true);
		//6. Execute the method found
		m5.invoke(obj, null);
	}
}

3 reflection practice

3.1 generic erasure

Think about how to add a string data to the existing ArrayList collection?

Let me tell you that there are no generic constraints in the. class file generated after program compilation. This phenomenon is called generic erasure. Then, we can add any type of element to the collection with generic constraints through reflection technology

The code is as follows:

public class ReflectTest {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		ArrayList<Integer> list = new ArrayList<Integer>();
		//Add element to collection
		list.add(new Integer(30));
		list.add(new Integer("12345"));
		list.add(123);
		//list.add("ha ha")// Because there are constraints on generic types
		System.out.println(list);
		
		//Through reflection technology, arbitrary types of elements can be added
		//1. Get bytecode file object
		//Class c = list.getClass();
		//Class c = ArrayList.class;
		Class c = Class.forName("java.util.ArrayList");
		
		//2. Find the add() method
		// public boolean add(E e)
		Method addMethod = c.getMethod("add", Object.class);
		
		//3. Execute the add() method
		addMethod.invoke(list, "ha-ha");// list.add("ha ha");
		System.out.println(list);
	}
}

3.1 reflection profile

Run the corresponding method of the specified class in the configuration file through the reflection configuration file

Read the data in the people.txt file and complete the creation of the Person object through reflection technology

The contents of the people.txt file are as follows:

className=cn.itcast_01_Reflect.Person
methodName=method5

Read the configuration file and call the corresponding method in the specified class

public class ReflectTest2 {
	public static void main(String[] args)
			throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchMethodException, SecurityException,
			InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// Reading data from a file through the Properties collection
		Properties prop = new Properties();
		// Read the data from the file into the collection
		prop.load(new FileInputStream("properties.txt"));
		// Gets the value corresponding to the key
		String className = prop.getProperty("className");
		System.out.println(className);

		// 1. Get the Person.class bytecode file object
		Class c = Class.forName(className);
		// 2. Obtain the construction method
		// public Person(String name, int age, String address)
		Constructor con = c.getConstructor(String.class, int.class, String.class);

		// 3. Create object
		Object obj = con.newInstance("Xiao Ming", 20, "China");
		System.out.println(obj);

		// 4. Get the specified method
		// private void method5(){}
		String methodName = prop.getProperty("methodName");
		Method m5 = c.getDeclaredMethod(methodName, null);
		// 5. Open violent visit
		m5.setAccessible(true);
		// 6. Execute the method found
		m5.invoke(obj, null);
	}
}

Posted by Rederick on Thu, 11 Nov 2021 10:05:08 -0800