1.1 understanding of reflection
Programs that can analyze class capabilities become reflective. Reflection is the key to being regarded as a dynamic language. The reflection mechanism allows programs to obtain the internal information of any class with the help of Reflection API during execution, and can directly operate the internal properties and methods of any object.
1.2 functions provided by reflection mechanism
- Determine the class of any object at run time
- Construct an object of any class at run time
- Judge the member variables and methods of any class at run time
- Get generic information at run time
- Call the member variables and methods of any object at run time
- Processing annotations at run time
- Generate dynamic proxy
1.3 Class
- Class loading process:
After the program passes the javac.exe command, it will generate one or more bytecode files (. End of class).
Then we use the java.exe command to interpret and run a bytecode file. It is equivalent to loading a bytecode file into memory. This process is called Class loading. The Class loaded into memory is called the runtime Class. This runtime Class is used as an instance of Class. - In other words, an instance of Class corresponds to a runtime Class.
- Runtime classes loaded into memory will be cached for a certain period of time. Within this time, we can get this runtime class in different ways.
1.3.1 several ways to obtain Class instances
Method 1: call the attribute of the runtime class:. Class
Class clazz1 = Person.class;
Method 2: call the getClass() method in the Object class through the Object of the runtime class
Person p1 = new Person();
Class clazz2 = p1.getClass();
Method 3: call the static method of Class: forName(String classPath)
Class clazz3 = Class.forName("review01.Person");
What is put in parentheses is the position where the Person class exists;
Method 4: use class loader: ClassLoader (understand)
public class test01 { @Test public void test001() throws ClassNotFoundException { ClassLoader classLoader = test01.class.getClassLoader(); classLoader.loadClass("review01.Person"); } }
1.4 use Classloader to load configuration files in src directory
-Method 1 for reading configuration files:
At this time, the file is under the current module by default
public class test01 { @Test public void test2() throws Exception { Properties pros = new Properties(); //At this time, the file is under the current module by default. //Method 1 for reading configuration files: FileInputStream fis = new FileInputStream("jdbc.properties"); //FileInputStream fis = new FileInputStream("src\\jdbc.properties"); pros.load(fis); } }
-Method 2 for reading configuration files:
At this time, the configuration file is under src of the current module by default
public class test01 { @Test public void test2() throws Exception { Properties pros = new Properties(); //The second way to read the configuration file is to use ClassLoader //The default identification of the configuration file is: under src of the current module ClassLoader classLoader = test01.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream("jdbc.properties"); pros.load(is); } }
1.5 reflection application 1: create objects of runtime classes
public class test01 { @Test public void test2() throws Exception { Class<Person> clazz = Person.class; Person obj = clazz.newInstance(); } }
Note:
newInstance(): call this method to create the object of the corresponding runtime class. Constructor that internally calls an empty parameter of the runtime class.
To create the object of the runtime class normally with this method, you need to:
1. The runtime class must provide a constructor with null parameters
2. The constructor of null parameter has sufficient access rights. Normally, it is set to public.
A public null parameter constructor is required in the javabean. reason:
1. It is convenient to create objects of runtime classes through reflection
2. When a subclass inherits this runtime class, it is ensured that the parent class is the constructor when super() is called by default
1.6 reflection application 2: obtain the complete structure of the runtime class
Through reflection, we can obtain all properties, methods, constructors, parent classes, interfaces, packages, annotations, exceptions, etc. in the corresponding runtime class...
-
Get attribute structure
getField(String name): or take the named attribute in the current runtime class and its parent class
getFields(): get the attributes declared as public access rights in the current runtime class and its parent class
Getdeclaraedfield(): get the named attribute in the current runtime class
Getdeclaraedfields(): get all the properties declared in the current runtime class. (excluding properties declared in the parent class) -
Acquisition method
getMethods(): get the method declared as public permission in the current runtime class and its parent class
Getdeclaraedmethods(): get all the methods declared in the current runtime class. (excluding methods declared in the parent class) -
Get constructor structure
getConstructors(): get the constructor declared as public in the current runtime class
Getdeclaraedconstructors(): get all constructors declared in the current runtime class -
Gets the parent class of the runtime class
getSuperclass() -
Gets the interface implemented by the runtime class
getInterfaces() -
Gets the package where the runtime class is located
getPackage() -
Gets the annotation of the runtime class declaration
getAnnotations()
1.6 reflection application 3: call the specified structure of the runtime class
- ① Call the specified property:
@Test public void testField() throws Exception { Class clazz = Person.class; //Create an object for the runtime class Person p = (Person) clazz.newInstance(); //1. Getdeclaraedfield (string fieldname): get the attribute of the specified variable name in the runtime class Field name = clazz.getDeclaredField("name"); //2. Ensure that the current attribute is accessible name.setAccessible(true); //3. Get and set the property value of the specified object name.set(p,"Tom");//void set(Object obj,Object newValue) sets the Field described by this Field object in the Obj object to a new value newValue System.out.println(name.get(p)); }
- ② Call the specified method:
@Test public void testMethod() throws Exception { Class clazz = Person.class; //Create an object for the runtime class Person p = (Person) clazz.newInstance(); /* 1.Gets a specified method getDeclaredMethod():Parameter 1: indicates the name of the obtained method parameter 2: indicates the formal parameter list of the obtained method */ Method show = clazz.getDeclaredMethod("show", String.class); //2. Ensure that the current method is accessible show.setAccessible(true); /* 3. invoke() of calling method: parameter 1: caller of method parameter 2: argument assigned to method parameter invoke()The return value is the return value of the method called in the corresponding class. */ Object returnValue = show.invoke(p,"CHN"); //String nation = p.show("CHN"); System.out.println(returnValue); }
Note:
public Object invoke(Object implicitParameter,Object[] explicitParameters)
Call the method described by this object, pass in the given parameter, and return the return value of the method.
For static methods, null is passed in as an implicit parameter.
- ③ Call the specified constructor:
@Test public void testConstructor() throws Exception { Class clazz = Person.class; /* 1.Gets the specified constructor getDeclaredConstructor():Parameters: indicates the list of parameters for the constructor */ Constructor constructor = clazz.getDeclaredConstructor(String.class); //2. Ensure that this constructor is accessible constructor.setAccessible(true); //3. Call this constructor to create the object of the runtime class Person per = (Person) constructor.newInstance("Tom"); }
Article reference:
b station: Java teaching video of song Hongkang, a teacher from Silicon Valley;
Java core technology Volume I