preface
Reflection is the soul of Java framework technology, learning reflection is very necessary, this article will be from the concept of entry, to practice, and then to explain the principle of reflection, I hope to help you.
Reflection to understand
The official resolution
Oracle’s official explanation for reflection is:
Reflection is commonly used by programs which require the ability to examine or
modify the runtime behavior of applications running in the Java virtual machine.
This is a relatively advanced feature and should be used only by developers who
have a strong grasp of the fundamentals of the language. With that caveat in
mind, reflection is a powerful technique and can enable applications to perform
operations which would otherwise be impossible.
Copy the code
Java’s reflection mechanism means that all properties and methods of any class can be known in the running state. And for any object, can call any of its methods; This ability to dynamically retrieve information and invoke object methods becomes the reflection mechanism of the Java language.
Vernacular understand
orthographic
Every Yin has a Yang, and every positive has an opposite. Since there is reflection, there must be orthotopic.
So what is orthophoto?
When we write code, when we need to use a class, we always know what that class does. Then we instantiate the class, and then we operate on the instantiated object, which is orthomorphism.
Student student = new Student();
student.doHomework("Mathematics");
Copy the code
reflection
Reflection is that we don’t know what class object we are initializing at first, and we can’t use the new keyword to create the object.
Class clazz = Class.forName("reflection.Student");
Method method = clazz.getMethod("doHomework", String.class);
Constructor constructor = clazz.getConstructor();
Object object = constructor.newInstance();
method.invoke(object, "Chinese");
Copy the code
Orthophoto versus reflection
The above two pieces of code, the execution effect is the same, as shown in the figure
However, the implementation process is quite different:
- The first piece of code already knows the class to run before it even runs
Student
; - The second piece of code is to run the entire program from the string
reflection.Student
, and know the class to operate onStudent
.
conclusion
Reflection is when you know what class to operate on at run time, and you can get the complete construct of the class at run time and call the corresponding method.
Class Object Understanding
To understand Class objects, let’s take a look at RTTI. Run-time Type Identification (RTTI) is used to identify the Type and class information of an object at runtime.
How does Java allow us to recognize information about objects and classes at run time? There are two main approaches: one is traditional RRTI, which assumes that all types are known at compile time. The other is reflection, which allows us to discover and use information about a class at runtime.
Each Class has a Class object, which is generated each time a new Class is compiled (or, more properly, stored in a.class file of the same name). For example, if you create a Student Class, the JVM creates a Class object for the Student Class that holds the type information associated with the Student Class.
The object of the Class Class is to provide or obtain information about the type of an object at runtime
Basic use of reflection
Gets the Class object
There are three ways to get a Class object in reflection.
First, use the class.forname static method.
Class class1 = Class.forName("reflection.TestReflection");
Copy the code
Second, use the.class method of the class
Class class2 = TestReflection.class;
Copy the code
Third, use the getClass() method of the instance object.
TestReflection testReflection = new TestReflection();
Class class3 = testReflection.getClass();
Copy the code
Reflection creates objects, gets methods, member variables, constructors
This section covers the basic API uses of reflection, such as fetching methods, member variables, and so on.
Reflection creates objects
There are two main ways to create class objects through reflection:
Example code:
Class class1 = class.forname ("reflection.Student"); Student student = (Student) class1.newInstance(); System.out.println(student); Class = class1. GetConstructor (); Student student1 = (Student) constructor.newInstance(); System.out.println(student1);Copy the code
Running results:
Reflection gets the constructor of the class
Here’s an example:
Class class1 = Class.forName("reflection.Student");
Constructor[] constructors = class1.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println(constructors[i]);
}
Copy the code
Reflection gets the member variables of a class
Look at the demo:
Email public class student {private Integer age; public String email; } public class TestReflection { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class class1 = Class.forName("reflection.Student");
Field email = class1.getField("email");
System.out.println(email);
Field age = class1.getField("age"); System.out.println(age); }}Copy the code
Running results:
getField(String name)
Not a public property
Reflection gets the method of the class
demo
public class Student {
private void testPrivateMethod() {
}
public void testPublicMethod() {
}
}
public class TestReflection {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class class1 = Class.forName("reflection.Student");
Method[] methods = class1.getMethods();
for(int i = 0; i < methods.length; i++) { System.out.println(methods[i]); }}}Copy the code
Running results:
How reflection works
From the previous section, we learned the basic API usage of reflection. Next, follow an example to learn the execution link of the reflection method.
public class TestReflection {
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("reflection.TestReflection");
Method method = clazz.getMethod("target", String.class);
method.invoke(null, "666"); } public static void target(String STR) {// Print stack information new Exception("#" +str).printStackTrace();
System.out.println("invoke target method"); }}Copy the code
Stack information reflects the reflection call link:
java.lang.Exception: # 666
invoke target method
at reflection.TestReflection.target(TestReflection.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at reflection.TestReflection.main(TestReflection.java:11)
Copy the code
The Invoke method executes a sequence diagram
Method invoke (); invoke ();
public Object invoke(Object obj, Object... The args) throws IllegalAccessException IllegalArgumentException, InvocationTargetException {/ / check permissionsif(! override) {if(! Reflection.quickCheckMemberAccess(clazz, modifiers)) { Class<? >caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor; // read volatile
if(ma == null) { ma = acquireMethodAccessor(); // Get MethodAccessor} // return methodAccessor.invokereturn ma.invoke(obj, args);
}
Copy the code
Method’s invoke Method returns interface MethodAccessor. The MethodAccessor interface has three implementation classes. Which class invoke method is invoked?
If you enter the acquireMethodAccessor method, you can see that MethodAccessor is determined by the newMethodAccessor method of the ReflectionFactory.
Again into ReflectionFactory newMethodAccessor method, we can see the returned is DelegatingMethodAccessorImpl object, invoke method that is invoked is it.
Then look at DelegatingMethodAccessorImpl invoke method
DelegatingMethodAccessorImpl the invoke method returns the MethodAccessorImpl invoke method, and MethodAccessorImpl invoke method, Overridden by its subclass NativeMethodAccessorImpl, which returns the native method invoke0, as follows
Therefore, the invoke Method is determined by invoke0, the local Method, and the underlying c++ Method is relevant.
Some applications and problems of reflection
Reflex application
Reflection is the soul of Java framework technology, many frameworks use reflection technology, such as Spring, Mybatis, Hibernate and so on.
JDBC database connection
In JDBC database connection, generally including loading drivers, database connection and other steps. Loading the driver is to load the driver of the database through class.forname (), i.e. reflection technology, after introducing the relevant Jar package.
Use of the Spring framework
Spring loads beans through an XML configuration schema, another classic example of reflection.
Loading process:
- Load the in-program XML configuration file into memory
- The Java class parses the contents of the XML to get the relevant bytecode information
- Use reflection to get an instance of Class
- To dynamically configure instance properties, use
There are certainly advantages to this:
You don’t have to go to the new instance every time, and you can modify the configuration file, which is more flexible.
Problems with reflection
Performance issues
Java reflection does not perform well, mainly because the compiler is unable to optimize the reflection-related code. For those who are interested, check out this article Java – Reflection – Why-is-it-SO-slow
Security issues
We know that during the design of the singleton pattern, emphasis is placed on making the constructor private, because this prevents objects from being constructed from outside. Reflection, however, can take fields, methods, and constructors from a class and modify access. So it’s not necessarily safe.
Take an example of an instantiation using a private constructor via reflection.
public class Student {
private String name;
private Student(String name) {
System.out.println("I'm a private constructor, I'm instantiated");
this.name = name;
}
public void doHomework(String subject) {
System.out.println("My name is." + name);
System.out.println("I'm doing it."+subject+"Homework");
}
}
public class TestReflection {
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("reflection.Student"); / / to get private Constructor object Constructor Constructor = clazz. GetDeclaredConstructor (String. Class); //trueObjects indicating reflection should be used without Java language access checks. constructor.setAccessible(true);
Student student = (Student) constructor.newInstance("jay@huaxiao");
student.doHomework("Mathematics"); }}Copy the code
Running results:
Security restrictions
Reference and thanks
- How reflection works
- Get the private constructor by reflection and use it
- Baymax: Java Reflection: Getting started, Using, and Working Principles
- Design Mode Singleton Mode 6 (Anti-Reflection Attack)
- Reflection: Application scenarios of the Java Reflection mechanism
- In-depth understanding of Java type information (Class objects) and reflection mechanisms
- Ideas for Java Programming
Personal public account
- If you are a good boy who loves learning, you can follow my public account and study and discuss with me.
- If you feel that this article is not correct, you can comment, you can also follow my public account, private chat me, we learn and progress together.