directory
1. The concept of reflection
1, concept,
2. How to get the bytecode file object
2.1 Concepts of metadata
2.2 Method of obtaining class Objects
3. How does reflection get metadata and access it
1. Access rights
2. Acquisition method
2.1 Accessing static methods
2.2 Accessing class methods
3. Get the field and read the value of the field
4. Get the implementation interface
5. Get the constructor and create the instance
Get the inherited parent class
7. Get annotations
4. Reflection examples
5, summary
Reflection is an advanced concept in Java, usually in the second half of the book. Reflection is also a necessary skill to write a framework. Reflection is very important. I still remember that I did not understand what reflection is in the first two years after graduation. Let’s talk about reflection today. I hope this article can help you solve the same puzzle. Without further ado, let’s get started.
1. The concept of reflection
1, concept,
Reflection refers to the running state, for any class, can know all the properties and methods of the class, for any object, can call any method. This ability to dynamically retrieve information and invoke object methods is called the Reflection mechanism of the Java language. Reflection is powerful, with advantages and disadvantages.
Advantages: High flexibility. Because reflection is dynamically compiled, that is, object instances are created and fetched dynamically only at run time.
Disadvantages: Low execution efficiency.
2. How to get the bytecode file object
2.1 Concepts of metadata
Metadata: Metadata is the code data used to describe a class. All class files loaded into the virtual machine are constructed into class objects. Class objects describe what a class has, including well-known implemented interfaces, inherited abstract classes, member variables, class variables, member methods, class methods, static methods, etc. This class object is metadata.
- Class: Represents a Class.
- Field class: Represents the member variables of the class (also known as attributes of the class).
- Method class: A Method that represents a class.
- Constructor class: represents the Constructor of a class.
2.2 Method of obtaining class Objects
-
2.2.1 By object, because any object must be associated with a class object
-
2.2.2 Directly obtained from class objects
-
2.2.3 Through the class loader, because the class loader reads the class file and returns a class object
Object to be used for reflection (a random object defined just for demonstration purposes)
package org.pdool.reflect; / * * *@authorParsley * / public class Npc { / / a static field public static int NPC_TYPE_1 = 1; // Private member variables private int npcType; // Share member variables public String name; // No argument constructor public Npc(a) {}// Has a parameter constructor public Npc(int npcType, String name) { this.npcType = npcType; this.name = name; } public int getNpcType(a) { return npcType; } public void setNpcType(int npcType) { this.npcType = npcType; } public String getName(a) { return name; } public void setName(String name) { this.name = name; } // Static method public static void sayHello(String word){ System.out.println("hello "+ word); }}Copy the code
Three ways to get a reflection class
package org.pdool.reflect; / * * *@authorParsley * / public class ClazzTest { public static void main(String[] args) { // The first way to get a Class object Npc npc1 = new Npc();// This new generates an Npc object, a Class object. Class npcClazz1 = npc1.getClass();// Get the Class object System.out.println(npcClazz1.getName()); // The second way to get a Class object Class npcClazz2 = Npc.class; System.out.println(npcClazz1 == npcClazz2);// Check whether the Class object obtained in the first way is the same as the Class object obtained in the second way // The third way to get a Class object try { Class npcClazz3 = Class.forName("org.pdool.reflect.Npc");// Note that this string must be the real path, i.e. the classpath with the package name, package name. The name of the class System.out.println(npcClazz3 == npcClazz2);// Check whether the three methods get the same Class object } catch(ClassNotFoundException e) { e.printStackTrace(); }}}Copy the code
3. How does reflection get metadata and access it
1. Access rights
The default behavior of reflection is limited by Java’s access controls, which can be bypassed by setAccessible.
// Sets the object array accessible flag
static void setAccessible(AccessibleObject[] array, boolean flag)
Copy the code
2. Acquisition method
2.1 Accessing static methods
public static void main(String[] args) throws NoSuchMethodException,InvocationTargetException, IllegalAccessException {
Npc npc = new Npc(1."The Demon God and the Female Phoenix.");
Class npcClazz = Npc.class;
// The first argument is the name of the method, and the second argument is the class object of the function
Method sayHello = npcClazz.getMethod("sayHello", String.class);
sayHello.invoke(npc, "world");
}
Copy the code
2.2 Accessing class methods
Npc npc = new Npc(1."The Demon God and the Female Phoenix.");
System.out.println(npc.getName());
Class npcClazz = Npc.class;
// The first argument is the name of the method, and the second argument is the class object of the function
Method sayHello = npcClazz.getMethod("setName", String.class);
sayHello.invoke(npc, "world");
System.out.println(npc.getName());
Copy the code
3. Get the field and read the value of the field
Npc npc = new Npc(1."The Demon God and the Female Phoenix.");
Class npcClazz = Npc.class;
// Get the field and set it accessible
Field field = npcClazz.getField("name");
field.setAccessible(true);
System.out.println( field.get(npc));
Copy the code
4. Get the implementation interface
5. Get the constructor and create the instance
Class npcClazz = Npc.class;
Constructor declaredConstructor = npcClazz.getDeclaredConstructor(int.class,String.class);
Npc npc = (Npc) declaredConstructor.newInstance(1."Demon god");
System.out.println(npc.getName());
Copy the code
Get the inherited parent class
Class npcClazz = Npc.class;
Class superclass = npcClazz.getSuperclass();
System.out.println(superclass.getName());
Copy the code
7. Get annotations
Class npcClazz = Npc.class;
Annotation[] annotations = npcClazz.getAnnotations();
// Runtime annotations
for (Annotation annotation : annotations) {
System.out.println(annotation.getClass().getName());
}
Copy the code
4. Reflection examples
It’s not the end goal to get the metadata, it’s the end goal to call the class at run time. For example, we all know how to implement IOC in Spring.
Process:
1. Spring reads the path of the bean configured in XML at project startup time.
2, then read the Class into the classloader through class.forname.
3. Then create all bean instances by reflection and store them in the container.
4. The bean object can be obtained directly in the project.
Let’s do this roughly, because XML is a bit of a chore to read, so we’ll use property instead. You can just experience the idea.
package org.pdool.reflect;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/ * * *@authorParsley * /
public class ClazzTest {
public static void main(String[] args){
try {
Map<String,Object> container = new HashMap<>();
1. Read the configuration
InputStream in = ClazzTest.class.getResourceAsStream("/beans.properties");
Properties property = new Properties();
property.load(in);
//2. Reflection creates objects
Set<Object> keySet = property.keySet();
for (Object key : keySet) {
// 2.1 Get the full path of the class
String classStr = (String) property.get(key);
// 2.2 Loading a class to a VMClass<? > beanClazz = Class.forName(classStr);// 2.3 Get the default constructorConstructor<? > declaredConstructor = beanClazz.getDeclaredConstructor();// 2.4 Creating an instance
Object o = declaredConstructor.newInstance();
container.put((String) key,o);
}
// 3. Obtain an instance
Npc npc = (Npc) container.get("npc");
System.out.println(npc == null);
} catch(Exception e) { e.printStackTrace(); }}}Copy the code
5, summary
When using Java reflection, the main steps include:
-
Gets the Class object of the target type
-
Get a Constructor object, a Method object, or a Field object from a Class object
-
The Constructor object, Method object and Field object are used to obtain the specific information of the Constructor, Method and attribute of the class, and the subsequent operations.
If you have any questions, you can leave a message and we can discuss it together. If you have no questions, you can leave a message and we can make friends
Typing is not easy, like, forward, pay attention to three even, thank you, by the way, pay attention to my public number: [cilantro chat game] there are more welfare oh