search
HomeJavajavaTutorialImplementation of Java reflection in JVM

Implementation of Java reflection in JVM

Feb 20, 2017 am 10:36 AM
javajvmreflection

1. What is Java reflection and what is it used for?

Reflection enables program code to access the internal information of classes loaded into the JVM, allowing code to be written and executed instead of selected classes in the source code, trading development efficiency for operational efficiency. the wrist of. This makes reflection a primary tool for building flexible applications.

Reflection can:

Call some private methods to achieve black technology. For example, sending dual-SIM text messages, setting the status bar color, automatically hanging up the phone, etc.

Implement serialization and deserialization, such as PO's ORM, Json parsing, etc.

Achieve cross-platform compatibility, such as the implementation of SocketImpl in JDK

Through xml or annotations, functions such as dependency injection (DI), annotation processing, dynamic proxy, unit testing, etc. are implemented. For example, Retrofit, Spring or Dagger

##2. The structure of Java Class file

In the *.class file, Class is stored in the form of Byte stream, through a After a series of Load and Parse, the Java code can actually be mapped to the structure in the figure below, which can be viewed using the

javap

command or IDE plug-in.



typedef struct {
    u4             magic;/*0xCAFEBABE*/
    u2             minor_version; /*网上有表可查*/
    u2             major_version; /*网上有表可查*/
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    //重要
    u2             fields_count;
    field_info     fields[fields_count];
    //重要
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}ClassBlock;

Constant pool (constant pool): Similar to the DATA segment and BSS segment in C, it provides constants, strings, method names and other values ​​or symbols (can be regarded as offset settings) Value pointer) storage


access_flags: flag modification of Class


 typedef enum {
      ACC_PUBLIC = 0x0001,
      ACC_FINAL = 0x0010,
      ACC_SUPER = 0x0020,
      ACC_INTERFACE = 0x0200,
      ACC_ACSTRACT = 0x0400
  }AccessFlag

this class/super class/interface: a pointer with length u2, pointing to the constant pool The real address in the link will be dereferenced during the Link phase.


filed: field information, the structure is as follows


typedef struct fieldblock {
     char *name;
     char *type;
     char *signature;
     u2 access_flags;
     u2 constant;
     union {
         union {
             char data[8];
             uintptr_t u;
             long long l;
             void *p;
             int i;
         } static_value; 
         u4 offset;
     } u;
  } FieldBlock;

method: Provide descriptor, access_flags, Code and other indexes, and point to the constant pool:


it The structure is as follows, details here


 method_info {
      u2             access_flags;
      u2             name_index;
      //the parameters that the method takes and the 
      //value that it return
      u2             descriptor_index;
      u2             attributes_count;
      attribute_info attributes[attributes_count];
  }

以上具体内容可以参考

JVM文档

周志明的《深入理解Java虚拟机》,少见的国内精品书籍

一些国外教程的解析


3. Java Class loading process

The loading of Class is mainly divided into two parts Step


The first step is to read and connect through ClassLoader

The second step is to initialize Class

<clinit>()

.



3.1. Classloader loading process

ClassLoader is used to load, connect, and cache Class, which can be implemented through pure Java or native. In the native code of the JVM, ClassLoader maintains a thread-safe

HashTable<String,Class>

internally, which is used to cache the decoded Class byte stream. If there is already a cache in the HashTable, the cache will be returned directly; otherwise , after obtaining the class name, deserialize it into a native C structure in the JVM by reading the class byte stream on the file and network, then malloc the memory, and cache the pointer in the HashTable.


The following is the process of ClassLoader in non-array situations

find/load: Deserialize the file into a C structure.


Implementation of Java reflection in JVM
Class deserialization process

link: Dereference symbols based on the Class structure constant pool. For example, object calculation memory space, creation of method table, native invoker, interface method table, finalizer function, etc.


3.2. Initialization process

When ClassLoader finishes loading Class, the Class will be initialized. Mainly executes the static code segments and static variables of

<clinit()>

(depending on the source code sequence).



public class Sample {
  //step.1
  static int b = 2;
  //step.2
  static {
    b = 3;
  }
  public static void main(String[] args) {
    Sample s = new Sample();
    System.out.println(s.b);
    //b=3
  }
}

具体参考如下:

When and how a Java class is loaded and initialized?

The Lifetime of a Type

After the initialization is completed, it is the construction of Object

<init>

, which will not be discussed in this article.



4. Implementation of reflection in native

Reflection can be called directly in Java, but the final call is still the native method. The following is the implementation of mainstream reflection operations.



4.1. Implementation of Class.forName

Class.forName can find Class objects through the package name, such as

Class.forName("java.lang.String")

.


In the JDK source code implementation, you can find that the native method

forName0()

is ultimately called. What it actually calls in the JVM is

findClassFromClassLoader()

. The principle is the same as the process of ClassLoader. Same, the specific implementation has been introduced above.



4.2. Implementation of getDeclaredFields

In the JDK source code, you can know that the

class.getDeclaredFields()

method actually calls the native method

getDeclaredFields0()

, its main implementation steps in JVM are as follows


According to the Class structure information, obtain the

field_count

and

fields[]

fields. This field has already been put in during the load process.


Allocate memory and create an array according to the size of

field_count


Perform a forEach loop on the array, and create Object objects sequentially through the information in

fields[]


Return array pointer


主要慢在如下方面

创建、计算、分配数组对象

对字段进行循环赋值


4.3. Implementation of Method.invoke

The following is without synchronization and exception Steps to call in this situation


Create Frame

If the object flag is native, hand it over to native_handler for processing

Execute java code in the frame

Pop up the Frame

Return the pointer of the execution result


主要慢在如下方面

需要完全执行ByteCode而缺少JIT等优化

检查参数非常多,这些本来可以在编译器或者加载时完成


4.4. Implementation of class.newInstance

Detect permissions, pre- Allocate space size and other parameters


Create Object object and allocate space

Call the constructor through Method.invoke (

<init>()

)


Return Object pointer


主要慢在如下方面

参数检查不能优化或者遗漏的查表

Method.invoke本身耗时


5. 附录

5.1. JVM与源码阅读工具的选择

初次学习JVM时,不建议去看Android Art、Hotspot等重量级JVM的实现,它内部的防御代码很多,还有android与libcore、bionic库紧密耦合,以及分层、内联甚至能把编译器的语义分析绕进去,因此找一个教学用的、嵌入式小型的JVM有利于节约自己的时间。因为以前折腾过OpenWrt,听过有大神推荐过jamvm,只有不到200个源文件,非常适合学习。

在工具的选择上,个人推荐SourceInsight。对比了好几个工具clion,vscode,sublime,sourceinsight,只有sourceinsight对索引、符号表的解析最准确。

5.2. 关于几个ClassLoader

参考这里

ClassLoader0:native的classloader,在JVM中用C写的,用于加载rt.jar的包,在Java中为空引用。

ExtClassLoader: 用于加载JDK中额外的包,一般不怎么用

AppClassLoader: 加载自己写的或者引用的第三方包,这个最常见

例子如下

//sun.misc.Launcher$AppClassLoader@4b67cf4d
//which class you create or jars from thirdParty
//第一个非常有歧义,但是它的确是AppClassLoader
ClassLoader.getSystemClassLoader();
com.test.App.getClass().getClassLoader();
Class.forName("ccom.test.App").getClassLoader()
//sun.misc.Launcher$ExtClassLoader@66d3c617
//Class loaded in ext jar
Class.forName("sun.net.spi.nameservice.dns.DNSNameService")
//null, class loaded in rt.jar
String.class.getClassLoader()
Class.forName("java.lang.String").getClassLoader()
Class.forName("java.lang.Class").getClassLoader()
Class.forName("apple.launcher.JavaAppLauncher").getClassLoader()

最后就是

getContextClassLoader()

,它在Tomcat中使用,通过设置一个临时变量,可以向子类ClassLoader去加载,而不是委托给ParentClassLoader

ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
try {
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    // call some API that uses reflection without taking ClassLoader param
} finally {
    Thread.currentThread().setContextClassLoader(originalClassLoader);
}

最后还有一些自定义的ClassLoader,实现加密、压缩、热部署等功能,这个是大坑,晚点再开。

5.3. 反射是否慢?

在Stackoverflow上认为反射比较慢的程序员主要有如下看法

验证等防御代码过于繁琐,这一步本来在link阶段,现在却在计算时进行验证

产生很多临时对象,造成GC与计算时间消耗

由于缺少上下文,丢失了很多运行时的优化,比如JIT(它可以看作JVM的重要评测标准之一)

当然,现代JVM也不是非常慢了,它能够对反射代码进行缓存以及通过方法计数器同样实现JIT优化,所以反射不一定慢。

更重要的是,很多情况下,你自己的代码才是限制程序的瓶颈。因此,在开发效率远大于运行效率的的基础上,大胆使用反射,放心开发吧。

 以上就是Java反射在JVM的实现 的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Why does the browser fail to correctly process the 401 status code when developing a WebSocket server using Netty?Why does the browser fail to correctly process the 401 status code when developing a WebSocket server using Netty?Apr 19, 2025 pm 07:21 PM

在使用Netty开发WebSocket服务器时,可能会遇到浏览器在尝试连接时未能正确处理服务器返回的401状态码的情况。 �...

Java compilation failed: What should I do if the javac command cannot generate the class file?Java compilation failed: What should I do if the javac command cannot generate the class file?Apr 19, 2025 pm 07:18 PM

Java compilation failed: Running window javac command cannot generate class file Many Java beginners will encounter this problem during the learning process: running window...

How to correctly divide business logic and non-business logic in hierarchical architecture in back-end development?How to correctly divide business logic and non-business logic in hierarchical architecture in back-end development?Apr 19, 2025 pm 07:15 PM

Discussing the hierarchical architecture problem in back-end development. In back-end development, common hierarchical architectures include controller, service and dao...

Java compilation error: How do package declaration and access permissions change after moving the class file?Java compilation error: How do package declaration and access permissions change after moving the class file?Apr 19, 2025 pm 07:12 PM

Packages and Directories in Java: The logic behind compiler errors In Java development, you often encounter problems with packages and directories. This article will explore Java in depth...

Is JWT suitable for dynamic permission change scenarios?Is JWT suitable for dynamic permission change scenarios?Apr 19, 2025 pm 07:06 PM

JWT and Session Choice: Tradeoffs under Dynamic Permission Changes Many Beginners on JWT and Session...

How to properly configure apple-app-site-association file in pagoda nginx to avoid 404 errors?How to properly configure apple-app-site-association file in pagoda nginx to avoid 404 errors?Apr 19, 2025 pm 07:03 PM

How to correctly configure apple-app-site-association file in Baota nginx? Recently, the company's iOS department sent an apple-app-site-association file and...

What are the differences in the classification and implementation methods of the two consistency consensus algorithms?What are the differences in the classification and implementation methods of the two consistency consensus algorithms?Apr 19, 2025 pm 07:00 PM

How to understand the classification and implementation methods of two consistency consensus algorithms? At the protocol level, there has been no new members in the selection of consistency algorithms for many years. ...

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.