Start Java again -- Reflection

Posted by sloede on Tue, 22 Oct 2019 09:02:05 +0200

concept

reflection: Introspection

Reflection: mirrors reflect sunlight
 A java class or object recognizes itself by looking in the mirror

How to realize the mirror in Java language?

The java.lang.reflect package provides the mirror API (application interface)

If you want to use an object of a certain type in the java.lang.reflect package, you need to obtain it through the java.lang.Class class class.

Get java.lang.Class object

  • Any object can get an object of its runtime type through the getClass() method

    	Class<?> c = o.getClass();
    	getClass() yes java.lang.Object Methods defined in class
    
  • The class object corresponding to any type of variable can be obtained through the class attribute.

    	Class<ArrayList> c = ArrayList.class;
    	Class<ArrayList> c = int.class;
    	Class<ArrayList> c = Integer.class;
    	byte[] bytes = new byte[10];
    	Class<?> c = byte[].getClass();
    
  • Obtain the class object of a class through the forName of the class

    	Class<?> c = Class.froName("com.ecti.Person"); // Provided that the specified class must be loadable
    

Specific examples are as follows:

public class GetInstance {
	public static void main(String[] args) throws Exception {
		Class<?> c = GetInstance.class;
		System.out.println( c );
		
		GetInstance g = new GetInstance();
		c = g.getClass();
		System.out.println( c );
		// How can an array get the corresponding Class type object?
		byte[] bytes= new byte[10];
		System.out.println( bytes );
		c = bytes.getClass();
		System.out.println( c );
		
		System.out.println( byte[].class);
		
		c = Class.forName("java.lang.Thread");
		System.out.println( c );
	}
}

Access the basic information of execution type through java.lang.Class object

  • Class name:
	getName(): package name. Class name
	getSimpleName(): class name
	getCanonicalName(): returns the normalized name of the underlying class defined in the Java language specification
  • Bag:
	getPackage(); returns the java.lang.Package object of the package where the current class is located
  • Parent class:
	getSuperclass() returns the direct parent of the Class (an object of Class type)
  • Which interfaces have been implemented:
	Class<?>[] interfaces = c.getInterfaces(); // Obtain the array of Class objects corresponding to the interface directly implemented by the current Class
  • Modifier:
	getModifiers(); returns integer coded Java language modifiers for this class or interface.
		Through toString in java.lang.reflect.Modifier class, integer encoded modifiers can be parsed into string form.
	String modifiers = Modifier.toString(i);
	If the return is an integer, the constant number corresponding to the corresponding modifier is added. For example, returning 25 is what 1 + 16 + 8 does.

An example is as follows:

public class TestClassMethod {
	public static void main(String[] args) {
		Class<?> c = Integer.class;
		System.out.println( c );
		System.out.println( c.getSimpleName() ); // Integer
		System.out.println( c.getName() );// java.lang.Integer
		System.out.println( c.getPackage() );
		System.out.println( c.getSuperclass() ); // class java.lang.Number
		System.out.println( c.getSuperclass().getSuperclass());
		/** What interfaces are obtained*/
		Class<?>[] clse = c.getInterfaces();
		for (Class<?> class1 : clse) {
			System.out.println( class1 );
		}
		
		int i = c.getModifiers(); 
		System.out.println( i );
		// Change the obtained modifier into a string to display
		String s= Modifier.toString(i);
		System.out.println(  s );
	}
}	

Get the properties in a class (Java. Lang. reflect. File)

Note: all of the following methods should be operated by Sinaean or by parent and child classes

Field        getDeclaredField(String name) 
	Returns the Field object corresponding to a single property of the specified name declared directly in this class
	Whether the attribute is private, default, protected, or public decorated 
Field[]     getDeclaredField()
	Returns an array of Field objects corresponding to all properties declared directly in this class
		
Field        getField(String name)
	public decorated properties declared from this class and inherited from the parent class (directly or indirectly)
	Gets the Field object of the property corresponding to the specified name
Field[]     getFields()
	Obtain the Field array corresponding to the public decorated property declared by this class and the public decorated property inherited from the parent class
public class GetField {
	
	public static void main(String[] args) throws Exception {
		Class<?> c = Class.forName("date170401am.reflect.Sinaean");
		System.out.println( c );
//		Field f = c.getField("name"); / / no problem found through the passed in name
//		
//		System.out.println( f );
		System.out.println("Properties are:");
		Field[] fs = c.getDeclaredFields();
		for (Field field : fs) {
			System.out.println( field );
		}
		System.out.println();
		
		Field f = c.getDeclaredField("name") ;
		System.out.println( f );
		
		 f = c.getField("face"); // Only public properties can be obtained
		 System.out.println( f );
		 
		 fs = c.getFields(); // Only the corresponding and public properties can be obtained
		 for (Field fl : fs) {
			 System.out.println( fl );
		}
		
		
	}
}

Get methods in a class

Method[]     c.getDeclaredMethods();
	Returns the Method object corresponding to all methods of the specified name declared directly in this class
	Whether the attribute is private, default, protected, or public decorated 
	
Method[]     c.getMethods();
	Obtain the Method array corresponding to the public decorated Method declared in this class and the public decorated Method inherited from the parent class
	
Method    	getDeclaredMethod(String name , Class<?>... parameterTypes)
	Get the Method object of the Method corresponding to the specified name and parameter list from the Method directly declared by this class
	
Method    	getMethod(String name , Class<?>... parameterTypes)
	Get the methods declared in this class and inherited from the parent class
	Method object of the method corresponding to the specified name and parameter list
public class GetMethod {
	public static void main(String[] args) throws Exception, Exception {
		// Note: in the Sinaean class, there should be a method composed of the modifiers of the permissions in 4
		// Parameters should be different
		Class<?> c = Sinaean.class;
		System.out.println( c );
		
		Method[] ms = c.getDeclaredMethods() ;
		for ( Method m : ms) {
			System.out.println( m );
		}
		
		System.out.println("~~~~~~ I am the gentle dividing line~~~~~~~~~");
		ms = c.getMethods();
		for (Method m : ms) {
			System.out.println( m );
		}
		
		System.out.println("~~~~~~ I am the gentle dividing line~~~~~~~~~");
		Method mt = c.getMethod("show", Integer.class , String.class, char.class , String.class);
		System.out.println( mt );
	}
}

Get the construction method in a class

Constructor [] getdeclaredconstructors(): get all the constructions declared in this class
	Constructor [] getconstructors(): obtain only the public decorated constructions of this class 
		
Constructor      getConstructors(Class<?>... parameterTypes)
	Obtain the corresponding construction method of the specified parameter list decorated by public in this class
	
Constructor      getDeclaredConstructor(Class<?>... parameterTypes)
	Get the construction method corresponding to the specified parameter list in this class (regardless of modifiers)
	Four construction methods are added to family, decorated with private, default, protected and public respectively.
	Four construction methods are added to Child, decorated with private, default, protected and public respectively.
		
	A class can have a constructor (overload of constructor), which requires different parameter lists.
	[constructor cannot be inherited]

Get the type defined inside a class

Class<?>       getDeclaredClasses()
Class<?>[]     getClasses()
public class GetAppClassLoaderInfos {

	public static void main(String[] args) {
		
		Class<?> c = GetAppClassLoaderInfos.class ;
		
		ClassLoader loader = c.getClassLoader();
		
		System.out.println( loader );
		
		Class<?> cl = loader.getClass() ; // Get the runtime type of the loader variable
		
		// Get the outer class of an inner class
		Class<?> outerClass = cl.getDeclaringClass() ; 
		System.out.println( outerClass.getName() );
		
		Field[] fields = cl.getDeclaredFields();
		
		System.out.println( cl.getSimpleName() + " The directly declared properties in the class are: " );
		for( Field f : fields ){
			System.out.println( f );
		}
		
		Method[] methods = cl.getDeclaredMethods();
		
		System.out.println( cl.getSimpleName() + " The methods directly declared in the class are: " );
		for( Method m : methods ){
			System.out.println( m );
		}
		
		Constructor<?>[] cons = cl.getDeclaredConstructors();
		
		System.out.println( cl.getSimpleName() + " The construction methods of declarations in a class are: " );
		for( Constructor<?> m : cons ){
			System.out.println( m );
		}
		
		Class<?>[] classes = cl.getDeclaredClasses();
		
		System.out.println( cl.getSimpleName() + " The inner types of declarations in a class are: " );
		for( Class<?> m : classes ){
			System.out.println( m );
		}
		
	}

}

Create an instance of a class by reflection

1. Create an instance of a class through class ා newinstance().
	Remember: this method depends on a public modified nonparametric construct inside the class.
	You can write a private construct to access the attempt
					
2. Create an instance of the class through constructor ා newinstance (object... Initargs)
	First obtain the construction method corresponding to the specified parameter list, and then pass the newInstance of the Constructor object
	The con.isAccessible() method can determine whether the con can be accessed (true means it can be accessed, false is the opposite)
	con.setAccessible(true); make it accessible
public class CreateInstance {
	public static void main(String[] args) throws Exception {
		Class<?> c = Class.forName("date170401am.reflect.Sinaean");
//		Object o =  c.newInstance();
//		System.out.println( o );
		
		Constructor<?> con = c.getDeclaredConstructor(Integer.class , String.class);
		Object o = con.newInstance(110 , "Summoner's Rift ");
		System.out.println( o );
		
		con = c.getDeclaredConstructor(Integer.class);
		con.setAccessible(true);
		o = con.newInstance(1234);
		System.out.println( o );
	}
}

Access attribute

1. Information about access properties
				
	Modifier field × getmodifiers()
	Type field × gettype()
	Name field × getname()
				
2. Set the value of a property and get the value of a property
	Field xxxField = c.getDeclaredField("name");
					
	Get the value of a property: xxxField.get(instance)
	Set the value of a property: xxxField.set(instance, value)
	f.isAccessible() method can determine whether con can be accessed (true means it can be accessed, false is the opposite)
	f.setAccessible(true); make it accessible
public class TestField {
	public static void main(String[] args) throws Exception {
//		Class<?> c = Class.forName("date170401am.reflect.Sinaean");
//		Field f = c.getDeclaredField("id"); / / get the property of the specified name
//		String modifiers = modifier.tostring (f.getmodifiers()); / / modifier
//		System.out.println("modifier is:" + modifiers);
//		Class<?> type = f.getType();
//		System.out.println( type );
//		
//		String name = f.getName(); 
//		System.out.println( name );
		
		Class<?> c = Class.forName("date170401am.reflect.Sinaean");
		Object o = c.newInstance();
		Field idField = c.getDeclaredField("id");
		System.out.println( idField );
		idField.setAccessible(true);
		Object v = idField.get(o); // o.id 
		System.out.println( v );
		idField.set(o, 1234); // o.setId( 1234 ) 
		 v = idField.get(o); // o.id 
		System.out.println( v );
	}
}

Access method

1. Information about access properties
public static void add( int a, int b) throws Exception{}
	Modifier: getModifiers()
	Return type: getReturnType()
	Method name: getName()
	Parameter list: getParameterTypes()
	Exception thrown: getExceptionTypes()

2. Call method
Object    Method#invoke( Object instance , Object .... args)
Participation
	instance indicates the method of the object to be called
	For example, m.invoke (O, key, value), which means calling the m method of map
										
	Variable length args indicates that the calling target method m is the parameter to be passed in
	For example, when calling Map put, you need to pass in key and value.
	m.invoke( map , key , value) 
Return
	invoke returns whatever the called target method m returns
	If the return type of the called target method is void, invoke returns null

When a method is private, if you want to access it, you can force it to access it
	Method#setAccessible( true ) ;
Access method
public class AccessMethodInfos {
	public static void main(String[] args)throws Exception {
		Class<?> c = Class.forName("date170401am.reflect.Sinaean");
		Method m = c.getDeclaredMethod("show", Integer.class);
		System.out.println( m );
		String modifiers = Modifier.toString( m.getModifiers() );
		System.out.println( modifiers);
		System.out.println( m.getReturnType() ); 
		System.out.println( m.getName() );
		Class<?>[] cls = m.getParameterTypes();
		for (Class<?> cl : cls) {
			System.out.println( cl );
		}
		System.out.println(  );
		Class<?>[] es = m.getExceptionTypes();
		for (Class<?> class1 : es) {
			System.out.println( class1 );
		}
		
	}
}
Calling method
public class CallMethor {
	public static void main(String[] args) throws Exception {
		Class<?> c = Class.forName("java.util.HashMap");
		Object hashMap = c.newInstance() ;
		Method m = c.getDeclaredMethod("put", Object.class , Object.class);
		
		// The instance method corresponding to m is called through reflection, so specific instance o needs to be specified.
		// The invoke method requires at least one parameter to specify which instance
		// The called target method m returns what it returns after execution
		// invoke returns null if the return type of the called target method m is void
		Object o = m.invoke(hashMap, "jqka" , 1234 ) ; // hashMap.put( key , value )
		System.out.println( o );
		
		 o = m.invoke(hashMap, "jqka" , 5678);
		System.out.println( o );
	}
}

Topics: Programming Java Attribute