Java reflection Usage Summary

Posted by ngu_tri on Thu, 09 Dec 2021 04:07:18 +0100

What is the reflection mechanism

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.

What can reflection mechanism do

The reflection mechanism mainly provides the following functions:

  • Judge the class of any object at run time;
  • Construct the object of any class at runtime;
  • Judge the member variables and methods of any class at run time;
  • Call the method of any object at run time;
  • Generate dynamic proxy.

API for reflection mechanism

**InterFace * * InterFace

package com.app;

public interface InterFace {

	void read() ;
	
}

Person class

package com.app;

public class Person  implements InterFace {

	private String id ;

	private String name ;

	public String age ;
	
	//Constructor 1
	public Person( ){

	}

	//Constructor 2
	public Person( String id ){
		this.id = id ;
	}

	//Constructor 3
	public Person( String id  , String name ){
		this.id = id ;
		this.name = name ;
	}


	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}


	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	/**
	 * Static method
	 */
	public static void update(){

	}


	@Override
	public void read() {

	}

}

  • Get class: 3 methods
package com.app;

public class T1 {

	public static void main(String[] args) {

		//The first method: forName
		try {
			Class<?> class1 = Class.forName("com.app.Person");

			System.out.println( class1 );
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}


		//The second method: class
		Class<?> class2 = Person.class;  

		//The third method: getClass
		Person person = new Person();  
		Class<?> class3 = person.getClass();

		System.out.println( class2 );
		System.out.println( class3 );
	}

}

Operation results:

class com.app.Person
class com.app.Person
class com.app.Person
  • Get all methods: getMethods()
package com.app;

import java.lang.reflect.Method;

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//Get all public methods
			Method[] methods = 	class1.getMethods() ;
			
			for (Method method : methods) {
				System.out.println( method );
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

Operation results:

//Custom method
public static void com.app.Person.update()
public java.lang.String com.app.Person.getName()
public void com.app.Person.read()
public java.lang.String com.app.Person.getId()
public void com.app.Person.setName(java.lang.String)
public void com.app.Person.setId(java.lang.String)

//Parent class Object class method
public final void java.lang.Object.wait() throws java.lang.InterruptedException
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 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 implemented interfaces: getInterfaces()
package com.app;

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//Get all interfaces
			Class<?>[] interS = class1.getInterfaces() ;

			for (Class<?> class2 : interS ) {
				System.out.println( class2 );
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

Operation results:

interface com.app.InterFace
  • Get parent class: getSuperclass()
package com.app;

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//Get parent class
			Class<?> superclass = class1.getSuperclass() ;

			System.out.println( superclass );

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

Operation results:

//The parent class is the Object class
class java.lang.Object
  • Get all constructors: getConstructors()
package com.app;

import java.lang.reflect.Constructor;

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//Get all constructors
			Constructor<?>[] constructors = class1.getConstructors() ;

			for (Constructor<?> constructor : constructors) {
				System.out.println( constructor );
			}


		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

Operation results:

public com.app.Person(java.lang.String,java.lang.String)
public com.app.Person(java.lang.String)
public com.app.Person()

  • Get all attributes: getdeclaraedfields();
package com.app;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//Get all properties of this class
			Field[] field = class1.getDeclaredFields();

			for (Field field2 : field) {
				System.out.println( field2 );
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

Operation results:

private java.lang.String com.app.Person.id
private java.lang.String com.app.Person.name
 

It can be seen that the attribute modifiers are: private, data type: String, name: id/name

  • Create instance: newInstance()
package com.app;


public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");;

			//Create instantiation: equivalent to new creating an object
			Object object = class1.newInstance() ;

			//Downward transformation
			Person person = (Person) object ;

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

	}
}

The difference between getDeclaredFields and getFields

getDeclaredFields() obtains all declared fields of a class, including public, private and protected, but excluding the declared fields of the parent class.

getFields() gets all the public fields of a class, including the parent class.

Small example

package com.app;

import java.lang.reflect.Field;

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");;

			//Get all field properties, including: 
			Field[] declaredFields = class1.getDeclaredFields() ;

			Field[] fields = class1.getFields() ;

			for( Field field : declaredFields ){
				System.out.println( "de--  " +  field  );
			}

			for( Field field : fields ){
				System.out.println( "fields--  " +  field  );
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}
}

Operation results:

de--  private java.lang.String com.app.Person.id
de--  private java.lang.String com.app.Person.name
de--  public java.lang.String com.app.Person.age
fields--  public java.lang.String com.app.Person.age

Actual combat 1: the method of obtaining object instances and operating objects through reflection

package com.app;


public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");;

			//Create instantiation: equivalent to new creating an object
			Object object = class1.newInstance() ;

			//Downward transformation				
			Person person = (Person) object ;
			
			person.setId( "100");
			person.setName( "jack") ; 
			
			System.out.println( "id: " + person.getId() + " name: " + person.getName()  );
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

	}
}

Operation results:

id: 100 name: jack

Practice 2: obtain the object field attribute through reflection and assign a value

package com.app;

import java.lang.reflect.Field;

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//Create instance
			Object person = class1.newInstance();

			//Get id attribute
			Field idField = class1.getDeclaredField( "id" ) ;
			
			//Assign a value to the id attribute
			idField.set(  person , "100") ;

			//Print the attribute value of person
			System.out.println( idField.get( person ));

		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace() ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}
}

Operation results:

java.lang.IllegalAccessException: Class com.app.T1 can not access a member of class com.app.Person with modifiers "private"
	at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
	at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
	at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
	at java.lang.reflect.Field.set(Unknown Source)
	at com.app.T1.main(T1.java:20)

The program crashed because the id attribute is private and its value cannot be modified.

improvement:

Add idfield.setaccessible (true);

The complete code is:

package com.app;

import java.lang.reflect.Field;

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//Create instance
			Object person = class1.newInstance();

			//Get id attribute
			Field idField = class1.getDeclaredField( "id" ) ;

			//In fact, setAccessible is a switch to enable and disable access security check. It can't be accessed if it's true. It can't be accessed if it's false  
            //Because the security check of JDK takes a lot of time, closing the security check by setAccessible(true) can improve the reflection speed  
			idField.setAccessible( true );
			
			//Assign a value to the id attribute
			idField.set(  person , "100") ;

			//Print the attribute value of person
			System.out.println( idField.get( person ));

		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace() ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}
}

Operation results:

100

Practice 3: comprehensive training, reflection operation attributes and methods

package com.app;

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

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//Create instance
			Object person = class1.newInstance();

			//Get id attribute
			Field idField = class1.getDeclaredField( "id" ) ;

			//In fact, setAccessible is a switch to enable and disable access security check. It can't be accessed if it's true. It can't be accessed if it's false  
			//Because the security check of JDK takes a lot of time, closing the security check by setAccessible(true) can improve the reflection speed  
			idField.setAccessible( true );

			//Assign a value to the id attribute
			idField.set(  person , "100") ;

			//Get setName() method
			Method setName = class1.getDeclaredMethod( "setName", String.class ) ;
			//Break the package 
			setName.setAccessible( true );

			//Call the setName method.
			setName.invoke( person , "jack" ) ;

			//Get name field
			Field nameField = class1.getDeclaredField( "name" ) ;
			//Break the package 
			nameField.setAccessible( true );

			//Print the id attribute value of person
			String id_ = (String) idField.get( person ) ;
			System.out.println( "id: " + id_ );

			//Print the name attribute value of person
			String name_ = ( String)nameField.get( person ) ;
			System.out.println( "name: " + name_ );
			
			//Get getName method
			Method getName = class1.getDeclaredMethod( "getName" ) ;
			//Break the package 
			getName.setAccessible( true );
			
			//Execute the getName method and receive the return value
			String name_2 = (String) getName.invoke( person  ) ;
			System.out.println( "name2: " + name_2 );

		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace() ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}
}

Operation results:

id: 100
name: jack
name2: jack

Practice 4: static attributes and static method calls

Define Util class

package com.app;

public class Util {

	public static String name = "json" ;

	/**
	 * No return value, no parameter
	 */
	public static void getTips(){
		System.out.println( "Yes---------1111");
	}

	/**
	 * There are return values and no parameters
	 */
	public static String getTip(){
		System.out.println( "Yes---------2222");
		return "tip2" ;
	}

	/**
	 * No return value, parameter
	 * @param name
	 */
	public static void getTip( String name ){
		System.out.println( "Yes---------3333 Parameters: " + name );
	}

	/**
	 * There are return values and parameters
	 * @param id
	 * @return
	 */
	public static String getTip( int id ){
		System.out.println( "Yes---------4444 Parameters: " + id );
		if ( id == 0 ){
			return "tip1 444 --1 " ;
		}else{
			return "tip1 444 --2" ;
		}
	}

}

Complete small example:

package com.app;

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

public class T1 {

	public static void main(String[] args) {

		try {
			//Create class
			Class<?> class1 = Class.forName("com.app.Util");

			//Get nameField property
			Field nameField = class1.getDeclaredField( "name" ) ;
			//Gets the value of nameField
			String name_ = (String) nameField.get( nameField ) ;
			//Output value
			System.out.println( name_ );


			//No return value, no parameter
			Method getTipMethod1 = class1.getDeclaredMethod( "getTips"  ) ; 
			getTipMethod1.invoke( null  ) ;
			
			//There are return values and no parameters
			Method getTipMethod2 = class1.getDeclaredMethod( "getTip"  ) ; 
			String result_2 = (String) getTipMethod2.invoke( null  ) ;
			System.out.println( "Return value: "+ result_2 );
			
			//No return value, parameter
			Method getTipMethod3 = class1.getDeclaredMethod( "getTip" , String.class  ) ; 
			String result_3 = (String) getTipMethod3.invoke( null , "The third method"  ) ;
			System.out.println( "Return value: "+ result_3 );
			
			//There are return values and parameters
			Method getTipMethod4 = class1.getDeclaredMethod( "getTip" , int.class ) ; 
			String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;
			System.out.println( "Return value: "+ result_4 );
			
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace() ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}
}

Operation results:

json
 Yes---------1111
 Yes---------2222
 Return value: tip2
 Yes---------3333 Parameter: third method
 Return value: null
 Yes---------4444 Parameter: 1
 Return value: tip1 444 --2

When the parameter is of int type and Integer type, the reflection acquisition method is different

  • When the parameter is of type int
    /**
	 * No return value, parameter
	 * @param id
	 */
	public static void getTip( int id ){
		
	}

When obtaining the method, you need to use: int.class. out of commission   Integer.class. Will report an error.

Method getTipMethod4 = class.getDeclaredMethod( "getTip" , int.class ) ; 
String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;
System.out.println( "Return value: "+ result_4 );
  • When the parameter is of type Integer
    /**
	 * No return value, parameter
	 * @param id
	 */
	public static void getTip( Integer id ){
		
	}

You need to use integer. Class to get the method. out of commission   int.class. Will report an error.

Method getTipMethod4 = class.getDeclaredMethod( "getTip" , Integer .class ) ; 
String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;
System.out.println( "Return value: "+ result_4 );

Create object instance

Person class

package com.app;

public class Person{

	private String id ;

	private String name ;


	//Constructor 1
	public Person( ){
		System.out.println( "Constructor has no arguments" );
	}

	//Constructor 2
	public Person( String id ){
		this.id = id ;
		System.out.println( "Constructor id : " + id );
	}

	//Constructor 3
	public Person( String id  , String name ){
		this.id = id ;
		this.name = name ;
		System.out.println( "Constructor id : " + id  + " name: " + name );
	}


	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

Create instance practice

package com.app;

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

public class T1 {

	public static void main(String[] args) {

		try {
			
			//Create class
			Class<?> class1 = Class.forName("com.app.Person");

			//non-parameter constructor 
			Object object = class1.newInstance() ;
			
			//Parameterized constructor: one parameter
			Constructor<?> constructor =  class1.getDeclaredConstructor( String.class ) ;
			constructor.newInstance( "1000" ) ;
			
			//Parameterized constructor: two parameters
			Constructor<?> constructor2 =  class1.getDeclaredConstructor( String.class , String.class ) ;
			constructor2.newInstance( "1001" , "jack" ) ;

		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace() ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}
}

Operation results

Constructor has no arguments
 Constructor id : 1000
 Constructor id : 1001 name: jack

summary

  • Class class provides four public methods for obtaining the constructor of a class.
Constructor getConstructor(Class[] params)     Returns a concrete with public Property constructor
Constructor getConstructors()     Return all with public Property
Constructor getDeclaredConstructor(Class[] params)     Returns a concrete constructor according to the constructor's parameters (regardless of public He Fei public Properties)
Constructor getDeclaredConstructors()    Returns an array of all constructors in this class (regardless of the type) public He Fei public Properties)
  • Four methods of obtaining members
Method getMethod(String name, Class[] params)    Returns a concrete method with public Property
Method[] getMethods()    Return all with public Property
Method getDeclaredMethod(String name, Class[] params)    Returns a specific method according to the method name and parameters public He Fei public Properties)
Method[] getDeclaredMethods()    Returns an array of all methods in this class (regardless of public He Fei public Properties)
  • Four methods to obtain member properties
Field getField(String name)    Returns a concrete variable with public Member variable of property
Field[] getFields()    Return with public Property
Field getDeclaredField(String name)    Returns a member variable (regardless of its name) public He Fei public Properties)
Field[] getDelcaredField()    Returns an array of all member variables, regardless of public He Fei public Properties)

Topics: Java Back-end Programmer architecture