Reflection mechanism of java language in java:
In the running state, the java reflection mechanism can know all the properties and methods of any class (class file);
For any object, it can call its Any method and attribute:
This dynamically obtained information and the kinetic energy of dynamically calling the object's method are called the reflection mechanism of the Java language.
Dynamicly obtaining information in a class is java reflection, which allows you to understand the anatomy of a class. Some applications cannot create new objects, but they can dynamically load classes to obtain class information.
As shown in the figure, just like a class is a description of an object, the Class class can describe a bytecode file (.class file) object.
//Early days: When new, first find the bytecode file of the class based on the name of the new class, and load it into the memory,
//Create the bytecode file object, and then create the The corresponding Person object of the bytecode file.
com.xidian.Person p=new com.xidian.Person();
//Now
String name="com.xidian.Person";
//Find the file class file, load it into the memory, and generate Class object.
Class clazz=Class.forName(name);
//How to generate an object of this class?
Object obj=clazz.newInstance();
Using the reflective class loading method, the form is more complex on the surface but the scalability is stronger. It used to be that you needed to manually create an object in the program file. Now you only need to write a string in the configuration file to create the corresponding object.
Question: Using clazz.newInstance() can only use the empty parameter constructor. What should I do if I want to use the parameter list constructor?
/*
* When obtaining the object embodied in the class corresponding to the specified name,* What should I do if the object is initialized without using the empty parameter constructor?
*
* Since the object is initialized through the specified constructor,
* so the constructor should be obtained first. This can be done through a bytecode file.
* The method is: getConstructor(parameterTypes)
*
* In reflection, constructors, fields, and methods are all objects.
*/
String name="com.xidian.Person";
Class clazz=Class.forName(name);
//Get the specified constructor object
Constructor constructor=clazz.getConstructor(String.class,int .class); //All data types can be described by bytecode files .class
//The object is initialized through the newInstance method of the constructor object.
Object obj=constructor.newInstance("xiaoming",12);
Get the value of the specified field:
//Check the school-wide permission to access private fields. Violent access.
field_1.setAccessible(true);
Object obj=clazz.newInstance();
field_1.set(obj,88);
Object o=field_1.get(obj);
System.out.println(o ; );
Method method2=clazz.getMethod("paramMethod",String.class,int.class); //Get the method with parameters, method name, parameter list
method2. invoke(obj2, "Xiaoqiang",89); //invoke: Call the underlying method represented by this Method object on the specified object with specified parameters.
Application of reflection:
Define an interface:
package com.xidian; public interface PCI { public void open(); public void close(); }
package com.xidian; public class SoundCard implements PCI{ public void open(){ System.out.println("sound open"); } public void close(){ System.out.println("sound close"); } }
package com.xidian; public class Mainboard { public void run(){ System.out.println("main run..."); } public void usePCI(PCI p){ if(p!=null){ p.open(); p.close(); } } }
Test:
package com.xidian; public class Test { public static void main(String[] args){ Mainboard mb=new Mainboard(); mb.run(); mb.usePCI(new SoundCard()); //如果主板需要使用其他设备,必须重新修改代码,传递一个新创建的对象,可扩展性不好。 } }
Although the use of interfaces has reduced the coupling of the program degree, but the scalability of the code is not good.
If you want to add a device to the motherboard but don’t want to modify the code, use reflection instead:
You don’t need to use new to complete it, but only get its class file, and inside it is the action of creating an object.
You should use .xml for configuration using reflection, which is more accurate. Here we use the properties object to achieve it.
Modify the main function code:
public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException{ Mainboard mb=new Mainboard(); mb.run(); //mb.usePCI(new SoundCard()); //如果主板需要使用其他设备,必须重新修改代码,可扩展性不好。 File configFile=new File("pci.properties"); Properties prop=new Properties(); //注意是将配置文件放在项目的一级目录下。 FileInputStream fis=new FileInputStream(configFile); prop.load(fis); for(int x=0;x<prop.size();x++){ String pciName=prop.getProperty("pci"+(x+1)); Class clazz=Class.forName(pciName); PCI p=(PCI)clazz.newInstance(); mb.usePCI(p); } fis.close(); } }
Configuration file pci.properties: pci1=com.xidian.SoundCard
When expanding the device, you only need to write the device program and the configuration file, without changing the main program The code is ready to use.