An overview,
According to the working principle of the virtual machine, under normal circumstances, the class takes: load – > validate – > prepare initialization – > analysis – > – > – > uninstall this process, if you need the reflection of the class does not in memory, then the first after loading the process, and in generating a class object in the memory, have the class object of reference, You can use your developer’s imagination and do what you want.
Function of reflection
- The need to access hidden properties or call methods to change the original logic of the program, this is very common in development, for some reason, the system does not open some interfaces, using reflection is an effective solution
- Custom annotations, which are retrieved at run time using reflection.
- Dynamic loading of classes in development, such as dynamic loading in Android to solve the 65K problem, modular and plug-in are inseparable from reflection, without reflection can not move forward.
Second, specific API
1, Java. Lang. Class Class
The java.lang.Class Class is the center of reflection in Java.
An object of the Class Class represents a Class in a runtime program. We can use the Class Class to look up information about a Class at run time.
We can get a reference to the Class object of our Class by:
- Use type-like text
Class<Test> testClass = Test.class;
Copy the code
Int. class and integer. TYPE refer to the same class object.
Class c = boolean.class;
c = Boolean.TYPE;
Copy the code
- Use the getClass() method of Object
class Test{
}
public class Main {
public static void main(String[] args) {
Test testRef = new Test();
Class testClass = testRef.getClass(); }}Copy the code
- Use the Class forName() method
// source code: Class<? >forName(String className) Class<? >forName(String Name, Boolean initialize, ClassLoader loader) // Example class MyClass {static {system.out.println ("Loading class MyClass...");
}
}
public class Main {
public static void main(String[] args) {
try {
String className = "MyClass";
boolean initialize = false;
ClassLoader cLoader = Main.class.getClassLoader();
Class c = Class.forName(className, initialize, cLoader);
className = "MyClass";
System.out.println("about to load"); // Will load and initialize the class c = Class.forName(className); } catch (ClassNotFoundException e) { System.out.println(e.getMessage()); }}}Copy the code
2. Java class reflection
We can use Java reflection to get information about a class, such as its package name, its access modifier, and so on, as follows:
- Get the name of the class
String simpleName = boolean.class.getSimpleName();
Copy the code
- Gets the modifier for the class
Class modifiers are the keywords that precede them. In Class declarations such as abstract, the getModifiers() method in public Class returns all of the Class’s modifiers, an integer. We must call the Java. Lang. Reflect. Modifier. ToString (int modifiers) to obtain the text form of the Modifier (test) to write code
- Get the name of the superclass (superclass)
Use the getSuperclass() method in Class. If the getSuperclass() method is called on the Object class, it will return NULL because it has no superclass.
- To get the names of all interfaces implemented by the class
Class[] interfaces = c.getInterfaces();
Copy the code
3. Java field reflection
We can use the java.lang.Reflect. Field class to get information about fields in the class. There are four types of Field objects that return fields in the Class:
- The getFields() method returns all accessible public fields declared in the class or inherited from the superclass.
Field[] getFields()
Copy the code
- The getDeclaredFields() method returns that all fields appear only in the class declaration (not from fields inherited).
Field[] getDeclaredFields()
Copy the code
- GetField (String Name) Gets the Field object by the Field name, including the parent class and the implemented interface class.
Field getField(String name)
Copy the code
- GetDeclaredField (String name) Gets the Field object by the Field name.
Field getDeclaredField(String name)
Copy the code
4. Java method reflection
Method Reflection keywords are as follows:
- methodsAn instance of the java.lang.Reflect. Method class represents one
methods
Inherits from a generic abstract superclassThe executable
– the Executable - parameter: method
parameter
Represented by an object of the Parameter class
The getParameters() method takes all parameters as an array of parameters. The getTypeParameters() method returns a TypeVariable array that represents the type parameters of a generic method or constructor
- The modifier: method
The modifier
The getModifiers() method returns modifiers as ints
Java constructor reflection
The Class Class gets information about constructors in four ways:
- The getConstructors() method returns all the public constructors of the current and superclass.
Constructor[] getConstructors()
Copy the code
- The getDeclaredConstructors() method returns all declared constructors for the current class.
Constructor[] getDeclaredConstructors()
Copy the code
- GetConstructor (Class… ParameterTypes) gets the constructor object by parameter type.
Constructor<T> getConstructor(Class... parameterTypes)
Copy the code
- GetDeclaredConstructor (Class… ParameterTypes) gets the constructor object by parameter type.
Constructor<T> getDeclaredConstructor(Class... parameterTypes)
Copy the code
Java reflection object creation
We can use reflection to create class objects on the fly. By calling one of the constructors. We can then access the values of the object’s fields, set their values, and call their methods.
- There are two ways to create a reflection object:
- Use the no-args constructor
- Use a constructor with arguments
- No argument constructor
If you have a reference to a Class object, you can create an object Class using newInstance() on the Class. This method takes no arguments and is the equivalent of the no-args constructor of a class that uses the new operator.
String s = String.class.newInstance();
Copy the code
- Constructor with arguments
Use reflection to create objects by calling specific constructors. The following is an example:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class MyClass {
public MyClass(int i, String s) {
System.out.println("called"); System.out.println(i); System.out.println(s); }} public class Main {public static void Main (String[] args) {class <MyClass> MyClass = myclass.class; Constructor<MyClass> cons = myclass.constructor (int. Class, String. Class); // MyClass Chris = cons.newInstance(1,"abc"); System.out.println(chris); } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { System.out.println(e.getMessage()); }}}Copy the code
- A method is called
Once you get the object from the constructor above, you can start calling the method, looking directly at the example:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class MyClass {
public MyClass() {
}
public void setName(String n) { System.out.println(n); }} public class Main {public static void Main (String[] args) {class <MyClass> MyClass = myclass.class; Try {// MyClass p = myclass.newinstance (); // step 3setName = myClass.getMethod("setName", String.class); // Call the method (static method can be null as the first argument, to be tested)setName.invoke(p, "abc"); } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) { System.out.println(e.getMessage()); }}}Copy the code
7, Java reflection field access
Reflection field access is divided into reading field value and setting field value, and the field access is not static or non-static (is the same).
import java.lang.reflect.Field;
class MyClass {
public String name = "Unknown";
public MyClass() {
}
public String toString() {
return "name="+ this.name; }} public class Main {public static void Main (String[] args) {class <MyClass> ppClass = myclass.class; Try {// MyClass p = ppclass.newinstance (); Field name = ppclass.getField ()"name"); / / if it is a private field, you need to add the following comments this step / / nameField setAccessible (true); String nameValue = (String) name.get(p); System.out.println("Current name is "+ nameValue); Name. Set (p, p)"abc");
nameValue = (String) name.get(p);
System.out.println("New name is "+ nameValue); } catch (InstantiationException | IllegalAccessException | NoSuchFieldException | SecurityException | IllegalArgumentException e) { System.out.println(e.getMessage()); }}}Copy the code
Java array reflection
- Creates arrays and manipulates the elements by reflection
import java.lang.reflect.Array;
public class Main {
public static void main(String[] args) {
try {
//int[] my = new int[2];
Object my = Array.newInstance(int.class, 2);
int n1 = Array.getInt(my, 0);
int n2 = Array.getInt(my, 1);
System.out.println("n1 = " + n1 + ", n2=" + n2);
Array.set(my, 0, 11);
Array.set(my, 1, 12);
n1 = Array.getInt(my, 0);
n2 = Array.getInt(my, 1);
System.out.println("n1 = " + n1 + ", n2="+ n2); } catch (NegativeArraySizeException | IllegalArgumentException | ArrayIndexOutOfBoundsException e) { System.out.println(e.getMessage()); }}}Copy the code
- Get the dimensions of an array, such as a three-dimensional array, by reflection
public class Main {
public static void main(String[] args) {
int[][][] intArray = new int[1][2][3];
System.out.println("int[][][] dimension is " + getArrayDimension(intArray));
}
public static int getArrayDimension(Object array) {
int dimension = 0;
Class c = array.getClass();
if(! c.isArray()) { throw new IllegalArgumentException("Object is not an array");
}
while(c.isArray()) { dimension++; // Array element type c = c.getComponentType(); } // The final array dimensionreturndimension; }}Copy the code
- Dynamically expand arrays by reflection
A Java array is a fixed-length data structure. To enlarge the array, we can create a larger array and copy the old array elements into the new array elements.
import java.lang.reflect.Array; import java.util.Arrays; public class Main { public static void main(String[] args) { int[] ids = new int[2]; System.out.println(ids.length); System.out.println(Arrays.toString(ids)); ids = (int[]) expandBy(ids, 2); ids[2] = 3; System.out.println(ids.length); System.out.println(Arrays.toString(ids)); } public static Object expandBy(Object oldArray, int increment) { Object newArray = null; int oldLength = Array.getLength(oldArray); int newLength = oldLength + increment; Class<? > c = oldArray.getClass(); newArray = Array.newInstance(c.getComponentType(), newLength); System.arraycopy(oldArray, 0, newArray, 0, oldLength);returnnewArray; }}Copy the code
3, recommend reflection tool class (source: Kotlin)
EasyReflect elegant reflection function library use method
EasyReflect elegant reflection function library source code
Fourth, concluding remarks
This article is a study note from Java Reflection
The article images and overview are from Java Reflection and its special application in Android
Thanks for reading!