The Java reflection mechanism is in the running state. For any class, you can know all the properties and methods of this class; for any object, you can call any methods and properties of it; this dynamically acquired information and dynamically called The function of an object method is called the reflection mechanism of the Java language. The concept of reflection was first proposed by Smith in 1982, mainly referring to a capability that a program can access, detect and modify its own state or behavior. The proposal of this concept quickly triggered research on applied reflectivity in the field of computer science. It was first adopted in the field of programming language design and achieved achievements in Lisp and object-oriented. Of course reflection itself is not a new concept. It may remind us of the concept of reflection in optics. Although computer science has given the concept of reflection new meaning, they do have some similarities in phenomenon. Helps us understand.
The Java reflection mechanism mainly provides the following uses:
Determine the class to which any object belongs at runtime
Construct objects of any class at runtime
Determine the member variables and methods of any class at runtime
Calling methods of any object at runtime
First, let’s take a look at a simple example, and use this example to understand how Java’s reflection mechanism works.
package com.wanggc.reflection;import java.lang.reflect.Method;/** * Java reflection exercises. * * @author Wanggc */public class ForNameTest { /** * entry function. * * @param args * Parameters * @throws Exception * Error message */ public static void main(String[] args) throws Exception { // Get Class Class<?> cls = Class.forNam e(args[0]); / / Obtain the corresponding object through Class Method[] methods = cls.getMethods(); // Output each method name for (Method method : methods) { System.out.println(method); } }}When the passed parameter is java.lang.String, the following result will be output
public boolean java.lang.String.equals(java.lang.Object)public java.lang.String java.lang.String.toString()public int java.lang.String.hashCode()pu blic int java.lang.String. compareTo(java.lang.String)public int java.lang.String.compareTo(java.lang.Object)public int java.lang.String.indexOf(int)public int java.lang.Strin g.indexOf(int,int) public int java.lang.String.indexOf(java.lang.String)public int java.lang.String.indexOf(java.lang.String,int)public static java.lang.String java.lang .String.valueOf(int )public static java.lang.String java.lang.String.valueOf(char)public static java.lang.String java.lang.String java.lang.String.valueOf(boolean)public static java.lang.St ring java.lang.String.valueOf( float)public static java.lang.String java.lang.String.valueOf(char[],int,int)public static java.lang.String java.lang.String.valueOf(double)public s tatic java.lang.String java .lang.String.valueOf(char[])public static java.lang.String java.lang.String.valueOf(java.lang.Object)public static java.lang.String java.lang.String. valueOf(long)public char java.lang.String.charAt(int)public int java.lang.String.codePointAt(int)public int java.lang.String.codePointBefore(int)public int java.lang.Str ing.codePointCount(int,int)public int java.lang.String.compareToIgnoreCase(java.lang.String)public java.lang.String java.lang.String.concat(java.lang.String)public boolean java.lang.String .contains(java.lang.CharSequence )public boolean java.lang.String.contentEquals(java.lang.CharSequence)public boolean java.lang.String.contentEquals(java.lang.StringBuffer)public stati c java.lang.String java.lang.String.copyValueOf(char[ ])public static java.lang.String java.lang.String.copyValueOf(char[],int,int)public boolean java.lang.String.endsWith(java.lang.String)public boolean java.lang.String.equalsIgnoreCase (java.lang.String)public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[])public static java.lang.String java.lang.St ring.format (java.util.Locale,java.lang.String,java.lang.Object[])public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEnc oddExceptionpublic void java.lang. String.getBytes(int,int,byte[],int)public byte[] java.lang.String.getBytes()public byte[] java.lang.String.getBytes(java.nio.charset.Char set)public void java .lang.String.getChars(int,int,char[],int)public native java.lang.String java.lang.String.intern()public boolean java.lang.String.isEmpty()public int j ava.lang. String.lastIndexOf(java.lang.String)public int java.lang.String.lastIndexOf(int,int)public int java.lang.String.lastIndexOf(int)public int java.lan g.String.lastIndexOf(java.lang. String,int)public int java.lang.String.length()public boolean java.lang.String.matches(java.lang.String)public int java.lang.String.offsetByCodePoin ts(int,int)public boolean java.lang .String.regionMatches(boolean,int,java.lang.String,int,int,int)public boolean java.lang.String.regionMatches(int,java.lang.String,int,int)public java.lan g.String java.lang .String.replace(java.lang.CharSequence,java.lang.CharSequence)public java.lang.String java.lang.String.replace(char,char)public java.lang.String java .lang.String.replaceAll(java .lang.String,java.lang.String)public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)public java.lang.String[] java.lan g.String .split(java.lang.String)public java.lang.String[] java.lang.String.split(java.lang.String,int)public boolean java.lang.String.startsWith(java.lang.St ring)public boolean java.lang.String.startsWith(java.lang.String,int)public java.lang.CharSequence java.lang.String.subSequence(int,int)public java.lang.String j ava.lang.String.substring(int )public java.lang.String java.lang.String.substring(int,int)public char[] java.lang.String.toCharArray()public java.lang.String java.lang.String.toLow erCase()public java. lang.String java.lang.String.toLowerCase(java.util.Locale)public java.lang.String java.lang.String java.lang.String.toUpperCase()public java.lang.String java.lang.String ing.toUpperCase(java.util. Locale)public java.lang.String java.lang.String.trim()public final native void java.lang.Object.wait(long) throws java.lang.InterruptedExceptionpub lic final void java.lang.Object.wait() throws java .lang.InterruptedExceptionpublic final void java.lang.Object.wait(long,int) throws java.lang.InterruptedExceptionpublic final native java.lang.Cla ss java.lang.Object.getClass()public final native void java.lang.Object. notify()public final native void java.lang.Object.notifyAll()
This lists all method names, their limiting characters, return types and thrown exceptions of the java.lang.String class. This program uses the Class class forName method to load the specified class, and then calls the getMethods method to return the method list of the specified class. java.lang.reflect.Method is used to express a single method in a certain class.
Using Java's reflection mechanism generally requires three steps:
Obtain the Class object you want to operate the class through the Class object obtained in the first step to obtain the method of the class or the method or attribute obtained in the second step of the operation of the class name.
When Java is running, no matter how many objects a certain class generates, they will correspond to the same Class object, which represents the class and interface in the running program. There are three common ways to obtain Class objects of the operation class:
Call Class's static method forName, as shown in the above example;
Use the .class syntax of the class, such as: Class<?> cls = String.class;
Call the getClass method of the object, such as: String str = "abc"; Class<?> cls = str .getClass();
The following will use an example to describe how to execute a certain method of an object through the three steps mentioned above:
package com.wanggc.reflection; import java.lang.reflect.Method; /** * Java reflection exercises. * * @author Wanggc */ public class ReflectionTest { public static void main(String[] args) throws Exception { DisPlay disPlay = new DisPlay(); // Get Class Class<?> cls = disPlay.getClass(); // Get the show method of the DisPlay class through Class Method method = cls.getMethod("show", String.class); // Call the show method method.invoke(disPlay, "Wanggc"); } } class DisP lay { public void show(String name) { System.out.println("Hello :" + name); } }As mentioned earlier, each class of a Java program will have a Class object corresponding to it. The first step in Java reflection is to obtain this Class object, such as 14 lines of code. Of course, each class's method must also have a Method object corresponding to it. To call this method through reflection, you must first obtain the method object of this method, such as line 16 of the code, and then use the method object to call this method in turn, such as line 18 of the code. Note that the first parameter of the getMethod method in line 16 is the method name, and the second is the parameter type of this method. If there are multiple parameters, then add the parameters, because getMethod is a variadic parameter method. Execute the invoke method of 18 lines of code, which is actually the show method. Note that the first parameter of invoke is an object of the DisPlay class, that is, the show method of which object of the DisPlay class is called. The second parameter is to pass it to the show method. parameters. The type and number must be consistent with the getMethod method of 16 lines.
The above example shows how to call a method of a certain class through reflection. The following example will explain how to assign values to properties of a certain class through reflection:
package com.wanggc.reflection; import java.lang.reflect.Field; /** * Java reflection property practice. * * @author Wanggc */ public class ReflectionTest { public static void main(String[] args) throws Exception { // Create student object Student student = new Student(); // Assign student object student.setStuName("Wanggc" ); student.setStuAge(); // Create copy target object Student destStudent = new Student(); // Copy the student object copyBean(student, destStudent); // Output copy result System.out.println(dest Student.getStuName() + ":" + destStudent.getStuAge()); } /** * Copy student object information. * * @param from * Copy the source object* @param dest * Copy the target object* @throws Exception * Exception */ private static void copyBean(Object from, Object dest) throws Exception { // Get the Class object of the copy source object Class< ?> fromClass = from.getClass(); // Get the attribute list of the copy source object Field[] fromFields = fromClass.getDeclaredFields(); // Get the Class object of the copy target object Class<?> destClass = dest.getClass() ; Field destField = null; for (Field fromField : fromFields) { // Get the attribute name of the copy source object String name = fromField.getName(); // Get the attribute of the same name of the copy target object destField = destC lass.getDeclaredField(name ); // Set the accessibility of the attribute fromField.setAccessible(true); destField.setAccessible(true); // Assign the value of the attribute of the copy source object to the corresponding attribute of the copy target object destField.set(dest, fromField. : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : get(from)); } } } /** * Student class. */ class Student { /** Name*/ private String stuName; /** Age*/ private int stuAge; /** * Get the student's name. * * @return Student Name*/ public String getStuName() { return stuName; } /** * Set student name* * @param stuName * Student Name*/ public void setStuName(String st uName) { this.stuName = stuName; } /** * Get student age* * @return Student age*/ public int getStuAge() { return stuAge; } /** * Set student age* * @param stuAge * Student age*/ public void setStuAge(int st uAge) { this.stuAge = stuAge; } }In the Java launch mechanism, the class corresponds to Class, the class methods correspond to Method, and of course the properties also correspond to Field. The comments in the code have been commented in detail and will not be repeated here. But be aware that Field provides get and set methods to get and set the values of attributes, but since the attribute is a private type, the accessibility of the attribute needs to be set to true, such as lines 50~51 of the code. You can also set accessibility for the entire fields and use the static method of AccessibleObject setAccessible under 40 lines, such as: AccessibleObject.setAccessible(fromFields, true);
The previous description shows how to use the Java reflection mechanism to operate the methods and properties of a class. The following is an example to describe how to create an object of a class at runtime:
package com.wanggc.reflection; import java.lang.reflect.Field; /** * Java reflection property practice. * * @author Wanggc */ public class ReflectionTest { public static void main(String[] args) throws Exception { // Create student object Student student = new Student(); // Assign student object student.setStuName("Wanggc" ); student.setStuAge(); // Create the copy target object Student destStudent = (Student) copyBean(student); // Output the copy result System.out.println(destStudent.getStuName() + ":" + destStudent.getStuAge( )); } /** * Copy student object information. * * @param from * Copy the source object* @param dest * Copy the target object* @throws Exception * Exception */ private static Object copyBean(Object from) throws Exception { // Get the copy Class object of source object Class<?> fromClass = from.getClass(); // Get the attribute list of the copy source object Field[] fromFields = fromClass.getDeclaredFields(); // Get the Class object of the copy target object Object ints = fromClass.newInstan ce(); for (Field fromField : fromFields) { // Set the accessibility of the attribute fromField.setAccessible(true); // Assign the value of the attribute of the copy source object to the corresponding attribute of the copy target object fromField.set(ints, fromField.get(from)); } return ints; } } /** * Student class. */ class Student { /** Name*/ private String stuName; /** Age*/ private int stuAge; /** * Get the student's name. * * @return Student Name*/ public String getStuName() { return stuName; } /** * Set student name* * @param stuName * Student Name*/ public void setStuName(String st uName) { this.stuName = stuName; } /** * Get student age* * @return Student age*/ public int getStuAge() { return stuAge; } /** * Set student age* * @param stuAge * Student age*/ public void setStuAge(int st uAge) { this.stuAge = stuAge; }}The result of this example and the previous example is the same. However, the object returned by the copyBean method is no longer passed in outside, but is generated internally by the method, as shown in the code on line 40. Note: Class's newInstance method can only create classes that contain constructors without parameters. If a certain class only has constructors with parameters, then another method must be used: fromClass.getDeclaredConstructor(int.class,String.class ).newInstance(24,"wanggc");
At this point, the common functions of the Java reflection mechanism (the method of calling objects at runtime, the use of class attributes, and the creation of class objects) have been introduced.
Supplement: When obtaining the methods, properties and constructors of the class, there are two corresponding methods: getXXX and getgetDeclaredXXX. The difference is that the former returns methods and properties with access rights public, including those in the parent class; but the latter returns methods and properties with access rights, not those in the parent class.
The above content is the Java launch mechanism introduced to you, I hope you like it.