Java reflection mechanism in-depth explanation, java reflection explanation
1. Concepts
Reflection maps various Java components into corresponding Java classes.
The Class construction method is private, which is created by JVM.
Reflection is a feature of the java language. It allows the program to perform self-check and perform operations on internal members at runtime (not during compilation. For example, it allows a java class to obtain and display all its member variables and methods. This capability of Java may not be used in many practical applications, but it does not exist in other programming languages. For example, Pascal, C, or C ++ cannot obtain information related to function definitions in the program. (From Sun)
JavaBean is one of the practical applications of reflection. It allows some tools to operate software components visually. These tools dynamically load and obtain the attributes of Java components (classes) through reflection.
Reflection exists from 1.2, and all the later three frameworks will use the reflection mechanism, which involves the Class "CLass" and cannot directly use new Class (). Its object is a bytecode in the memory.
An instance of the Class indicates the classes and interfaces in the running Java application. Enumeration is a type, and annotation is an interface. Each array is a Class mapped to a Class Object. All arrays with the same element type and dimension share the Class object. Basic Java types (boolean, byte, char, short, int, long, float, and double) and keywords void are also represented as Class objects. Class does not have a public constructor. The Class object is automatically constructed by the Java Virtual Machine during Class loading and by calling the defineClass method in the Class loader.
1 Person p1 = new Person (); 2 // The following three methods can obtain the bytecode 3 CLass c1 = Date. class (); 4 p1.getClass (); 5 // load if it exists. Otherwise, the third type is often used. You do not need to know the class name when writing the source program, to the runtime and then pass 6 Class. forName ("java. lang. string ");
CLass. the forName () bytecode has been loaded into the Java Virtual Machine to obtain the bytecode. the Java Virtual Machine has not yet generated the bytecode to load with the class loader, And the loaded bytecode is buffered into the virtual machine.
The following simple example shows how reflection works.
import java.lang.reflect.*; public class DumpMethods { public static void main(String args[]) { try { Class c = Class.forName("java.util.Stack"); Method m[] = c.getDeclaredMethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i].toString()); } catch (Throwable e){ System.err.println(e); } } }
1 public synchronized java.lang.Object java.util.Stack.pop() 2 public java.lang.Object java.util.Stack.push(java.lang.Object) 3 public boolean java.util.Stack.empty() 4 public synchronized java.lang.Object java.util.Stack.peek() 5 public synchronized int java.util.Stack.search(java.lang.Object)
In this way, the names of java. util. Stack classes and their delimiters and return types are listed. This program uses Class. forName to load the specified Class, and then calls getDeclaredMethods to obtain the list of methods defined in this Class. Java. lang. reflect. Methods is a class used to describe a single method in a class.
The following example uses a Class object to display the Class name of an object:
1 void printClassName(Object obj) {2 System.out.println("The class of " + obj +3 " is " + obj.getClass().getName());4 }
You can also use a Class literal value (JLS Section 15.8.2) to obtain Class objects of the specified type (or void. For example:
1 System.out.println("The name of class Foo is: "+Foo.class.getName());
When there is no object instance, there are two main methods.
// Obtain the Class type in two ways: class cls1 = Role. Class; Class cls2 = Class. forName ("yui. Role ");
Note that in the second method, the forName parameter must be a complete Class Name (package name + class name), and this method needs to capture exceptions. Now cls1 can be used to create an instance of the Role Class. The newInstance method of the Class is equivalent to the default constructor of the calling Class.
1 Object o = cls1.newInstance (); 2 // create an instance 3 // Object o1 = new Role (); // equivalent to the above method
Ii. Common Methods
1. isPrimitive (determine whether it is a basic type of bytecode)
Public class TestReflect {public static void main (String [] args) {// TODO Auto-generated method stub String str = "abc"; Class cls1 = str. getClass (); Class cls2 = String. class; Class cls3 = null; // null must be added. try {cls3 = Class. forName ("java. lang. string ");} catch (ClassNotFoundException e) {// TODO Auto-generated catch block e. printStackTrace ();} System. out. println (cls1 = cls2); System. out. printl N (cls1 = cls3); System. out. println (cls1.isPrimitive (); System. out. println (int. class. isPrimitive (); // determines whether the specified Class object represents a basic type. System. out. println (int. class = Integer. class); System. out. println (int. class = Integer. TYPE); System. out. println (int []. class. isPrimitive (); System. out. println (int []. class. isArray () ;}}/** truetruefalsetruefalsetruefalsetrue */*/
2. getConstructor and getConstructors ()
In java, constructor methods are not sequenced by the type and number of parameters.
1 public class TestReflect {2 public static void main(String[] args) throws SecurityException, NoSuchMethodException {3 // TODO Auto-generated method stub4 String str = "abc";5 6 System.out.println(String.class.getConstructor(StringBuffer.class));7 }8 }
3. The Filed class represents a member variable in a certain category.
1 import java. lang. reflect. field; 2 public class TestReflect {3 public static void main (String [] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, Exception, Exception {4 ReflectPointer rp1 = new ReflectPointer (3,4 ); 5 Field fieldx = rp1.getClass (). getField ("x"); // It must be x or y 6 System. out. println (fieldx. get (rp1); 7 8/* 9 * private member variables must use getDeclaredField, and setAccessible (true ), otherwise, we cannot get 10 */11 Field fieldy = rp1.getClass (). getDeclaredField ("y"); 12 fieldy. setAccessible (true); // brute force reflection 13 System. out. println (fieldy. get (rp1); 14 15} 16} 17 18 class ReflectPointer {19 20 public int x = 0; 21 private int y = 0; 22 23 public ReflectPointer (int x, int y) {// alt + shift + s is equivalent to right-clicking source24 super (); 25 // TODO Auto-generated constructor stub26 this. x = x; 27 this. y = y; 28} 29}
4.
Iii. Typical examples
1. Change B in all String member variables to.
1 import java. lang. reflect. field; 2 public class TestReflect {3 public static void main (String [] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, Exception, Exception {4 ReflectPointer rp1 = new ReflectPointer (3,4 ); 5 changeBtoA (rp1); 6 System. out. println (rp1); 7 8} 9 10 private static void changeBtoA (Object obj) throws RuntimeException, Exception {11 Field [] fields = obj. getClass (). getFields (); 12 13 for (Field field: fields) {14 // if (field. getType (). equals (String. class) 15 // because the bytecode only has one copy, the equals semantics is not accurate 16 if (field. getType () = String. class) {17 String oldValue = (String) field. get (obj); 18 String newValue = oldValue. replace ('B', 'A'); 19 field. set (obj, newValue); 20} 21} 22} 23} 24 25 class ReflectPointer {26 27 private int x = 0; 28 public int y = 0; 29 public String str1 = "ball"; 30 public String str2 = "basketball"; 31 public String str3 = "itcat"; 32 33 public ReflectPointer (int x, int y) {// alt + shift + s is equivalent to right-clicking source34 super (); 35 // TODO Auto-generated constructor stub36 this. x = x; 37 this. y = y; 38} 39 40 @ Override41 public String toString () {42 return "ReflectPointer [str1 =" + str1 + ", str2 =" + str2 + ", str3 = "43 + str3 +"] "; 44} 45}
2. Write a program to call the main method in the class based on the class name provided by the user.
Why is reflection required?
1 import java. lang. reflect. field; 2 import java. lang. reflect. method; 3 4 public class TestReflect {5 public static void main (String [] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {6 String str = args [0]; 7/* 8 * indicates that the array badge is out of the range. Because this character array does not exist at all, 9 * needs to be right-clicked and input B in run as-events-arguments. inter (complete Class Name) 10*11 */12 Method m = Class. forName (str ). getMethod ("main", String []. class); 13 // either of the following methods is acceptable. The main method requires a parameter of 14 15 m. invoke (null, new Object [] {new String [] {"111", "222", "333"}); 16 m. invoke (null, (Object) new String [] {"111", "222", "333"}); // this can be explained, the array is also Object17/* 18 * m. invoke (null, new String [] {"111", "222", "333"}) 19 * cannot, because java will automatically unpack 20 */21} 22} 23 24 class Inter {25 public static void main (String [] args) {26 for (Object obj: args) {27 System. out. println (obj); 28} 29} 30}
3. Simulate the instanceof Operator
class S { } public class IsInstance { public static void main(String args[]) { try { Class cls = Class.forName("S"); boolean b1 = cls.isInstance(new Integer(37)); System.out.println(b1); boolean b2 = cls.isInstance(new S()); System.out.println(b2); } catch (Throwable e) { System.err.println(e); } } }
In this example, a Class Object of the S Class is created, and then check whether some objects are S instances. Integer (37) is not, but new S () is.
Iv. Method class
Represents a method in a class (not an object.
1 import java. lang. reflect. field; 2 import java. lang. reflect. method; 3/* 4 * A person draws a circle on the blackboard, involving three objects. The circle needs the center and radius, but is private. It is not appropriate to assign the Circle Method to others. 6*7 * The driver only sends a command to the train to step on the brakes. The brake operation must be completed by the train. 8*9 * The interview often involves object-oriented design. For example, when people close their doors, they just push the door. 10*11 * this is the expert mode: The method is assigned to 12 */13 public class TestReflect {14 public static void main (String [] args) who owns the data and who is the expert) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {15 String str = "shfsfs"; 16 // The package starts with com, which indicates sun is used internally, java headers are the user's 17 Method mtCharAt = String. class. getMethod ("charAt", int. class); 18 Object ch = mtCharAt. invoke (str, 1); // if the first parameter is null, it must be the static method 19 System. out. println (ch); 20 21 System. out. println (mtCharAt. invoke (str, new Object [] {2}); // 1.4 syntax 22 23} 24 25}
5. array reflection
The Array tool class is used to perform Array reflection.
The same type and latitude have the same bytecode.
Int. class and Integer. class are not the same bytecode. Integer. TYPE indicates the bytecode of the basic class corresponding to the packaging class. int. class = Integer. TYPE
1 import java. util. arrays; 2 3/* 4 * from this example, we can see that even if the bytecode is the same but the object is not necessarily the same, it's not the same thing 5*6 */7 public class TestReflect {8 public static void main (String [] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, exception {9 int [] a = new int [3]; 10 int [] B = new int [] {, 5}; // The length cannot be specified after direct assignment, otherwise, CE11 int [] [] c = new int [3] [2]; 12 String [] d = new String [] {"jjj", "kkkk "}; 13 System. out. println (a = B); // false14 System. out. println (. getClass () = B. getClass (); // true15 // System. out. println (. getClass () = d. getClass (); // compare bytecode a and cd. out. println (. getClass (); // output class [I17 System. out. println (. getClass (). getName (); // output [I, brackets represent arrays, And I represents an integer of 18 19 System. out. println (. getClass (). getSuperclass (); // output class java. lang. object20 System. out. println (d. getClass (). getSuperclass (); // output class java. lang. object21 22 // because the parent class is all objects, the following can be 23 Object obj1 = a; // not Object [] 24 Object obj2 = B; 25 Object [] obj3 = c; // an array of the basic type can only be used as an Object, and must be used as an Object [] 26 Object obj4 = d; 27 28 // note the difference between asList processing int [] and String [] 29 System. out. println (Arrays. asList (B); // 1.4 No variable parameter. The array is used, [[I @ 1bc4459] 30 System. out. println (Arrays. asList (d); // [jjj, kkkkk] 31 32} 33}
Vi. Conclusion
The above is the simple use of the reflection mechanism. Obviously, those who have learned spring understand why we can get the specified methods and variables through the configuration file, when we create an Object, it is implemented by passing it into the string, as if you need something, we will produce it for you, and we have been using the Object, which shows the dynamic characteristics of the java language, the dependency is greatly reduced.
Notes for learning Java !!!
If you have any questions or want to obtain learning resources during the learning process, join the Java learning exchange group: 159610322 let's learn Java together!