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)