Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the problems with Java reflection

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "what are the problems about Java reflection". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what are the problems about Java reflection"?

Can reflection modify final type member variables?

Final we should all know that when you modify a variable, it represents a constant and cannot be modified. Can the effect of modification be achieved by using reflection energy?

Let's first try to modify a String variable decorated with final.

Public class User {private final String name = "Bob"; private final Student student = new Student (); public String getName () {return name;} public Student getStudent () {return student;}} User user = new User (); Class clz = User.class; Field field1= null; try {field1=clz.getDeclaredField ("name"); field1.setAccessible (true) Field1.set (user, "xixi"); System.out.println (user.getName ());} catch (NoSuchFieldException e) {e.printStackTrace ();} catch (IllegalAccessException e) {e.printStackTrace ();}

The printed result is still Bob, that is, it has not been modified.

Let's modify the student variable again:

Field1 = clz.getDeclaredField ("student"); field1.setAccessible (true); field1.set (user, new Student ()); print: com.example.studynote.reflection.Student@77459877 before modification and com.example.studynote.reflection.Student@72ea2f77 after modification

As you can see, normal object variables can be modified by reflection even if they are modified by final.

Why is that? Why can't String be modified while ordinary object variables can be modified?

Let's come to the conclusion that the string value has also been modified, but we can't get the modified value through this object.

This involves inline optimization of JVM:

Inline function, the compiler inserts the specified function body and replaces each place where the function is called (context), thus saving the extra time cost of each function call.

To put it simply, JVM will help us optimize the code logic when dealing with the code, such as the above final variable, it is known that the final modification will not be modified, so getting this variable will directly help you assign a value in the compilation phase.

So after JVM compilation and inline optimization, the above getName method becomes:

Public String getName () {return "Bob";}

So no matter how much you modify, you can't get the modified value.

Some friends may propose to obtain name directly. Like this:

/ / change to public public final String name = "Bob"; / / print user.name field1=clz.getDeclaredField ("name"); field1.setAccessible (true); field1.set (user, "xixi"); System.out.println (user.name) after reflection modification

I'm sorry, it's better to print out Bob. This is because the sentence System.out.println (user.name), when compiled, is written as follows:

System.out.println (user.name) / / optimized inline System.out.println ("Bob")

So:

"reflection can modify the final variable, but in the case of a basic data type or a String type, the modified value cannot be obtained through the object because it is inline optimized by JVM. "

Is there any way to get the modified value?

Yes, you can obtain it through the Field.get (Object obj) method in reflection:

/ / get the value of the variable corresponding to field in the user object System.out.println ("modified" + field.get (user))

Reflection acquires static static variables

After talking about final, let's talk about static, how to modify the variables modified by static?

We know that static variables are initialized before the class is instantiated (the initialization phase of the class), so static variables follow the class itself and have nothing to do with the specific object, so we don't need to pass in the object to get the variable, just pass it to null:

Public class User {public static String name;} field2 = clz.getDeclaredField ("name"); field2.setAccessible (true); / / get static variable Object getname=field2.get (null); System.out.println ("before modification" + getname); / / modify static variable field2.set (null, "xixi"); System.out.println ("modified" + User.name)

Such as the above code:

Field.get (null) can get static variables.

Field.set (null,object) can modify static variables.

How to improve reflection efficiency

1. Cache reused objects

Using caching, in fact, I don't need to say that everyone knows that objects that are used many times in normal projects will also be cached, and no one will create them many times.

However, this is particularly important in reflection, such as the Class.forName method, and let's do a test:

Long startTime = System.currentTimeMillis (); Class clz = Class.forName ("com.example.studynote.reflection.User"); User user; int i = 0; while (I < 1000000) {iTunes; / / method 1, directly instantiate user = new User () / / method 2, get class by reflection each time, and then instantiate user = (User) Class.forName ("com.example.studynote.reflection.User"). NewInstance (); / / method 3, instantiate user = (User) clz.newInstance () through the class obtained by previous reflection;} System.out.println ("time consuming:" + (System.currentTimeMillis ()-startTime))

Print the results:

1. Time to instantiate directly: 152. Get class by reflection every time, and then instantiate: 671 3. Time to instantiate through class obtained by previous reflection: 31.

So we can see that as long as we make reasonable use of these reflection methods, such as Class.forName,Constructor,Method,Field, and cache the instances outside the loop as far as possible, we can improve the efficiency of reflection and reduce time-consuming.

2. SetAccessible (true)

We said earlier that the setAccessible (true) method is used to turn off security checks when private variables and methods are encountered. This security check is actually time-consuming.

So we can try our best to call setAccessible (true) to turn off the security check, whether it is private or not, which can also improve the efficiency of reflection.

3 、 ReflectASM

ReflectASM is a very small Java class library that provides high-performance reflection processing through code generation, automatically provides access classes for get/set fields, and access classes use bytecode manipulation instead of Java's reflection technology, so it is very fast.

ASM is a general Java bytecode manipulation and analysis framework. It can be used to modify existing classes or to dynamically generate classes directly in binary form.

In a nutshell, this is a high performance library that is similar to reflection, but different from reflection. His principle is to generate a new class through the ASM library, and then it is equivalent to directly calling the new class method to complete the reflection function.

Those who are interested can take a look at the source code, the implementation principle is relatively simple-https://github.com/EsotericSoftware/reflectasm.

"small summary:" after the above three methods, I think reflection will not be so scary that it will greatly affect performance. If you really find that reflection affects performance and actual use, you may be able to study it. Is it because it is useless for reflection and does not handle the reflection-related cache?

Reflection principle

If we try to look at the source code of these reflection methods, we will find that we will end up in the native method, such as

The getDeclaredField method goes to the

Public native Field getDeclaredField (String name) throws NoSuchFieldException

So at the bottom, how do you get the information about the class?

First, review the process of loading the Java file by JVM:

During the compilation phase, .java files are compiled into .class files, which are binary files that contain machine code that JVM can recognize.

The .class file stores all kinds of information about the class file in turn, such as: version number, class name, field description and descriptor, method name and description, whether it is public, class index, field table collection, method collection and so on.

The class loader in JVM then reads the bytecode file, fetches the binary data, loads it into memory, and parses the .class file's information.

The class loader takes the binary byte stream of the class and generates a java.lang.Class object that represents the class in memory.

Finally, the lifecycle of the class begins, such as connection, initialization, and so on.

Reflection, however, is to manipulate the java.lang.Class object, which has the structure of the entire class, including property methods, and so on.

To sum up, .class is a sequential structure file, and the Class object is a representation of this file, so we can get all the information about the class from the Class object, which is the principle of reflection.

Thank you for your reading, the above is the content of "what are the problems about Java reflection". After the study of this article, I believe you have a deeper understanding of the problem of Java reflection, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report