字符串常量池 -String.intern 源码实现 3/3
String.intern()
是 Java 中用于操作字符串常量池的关键方法。它的作用是将字符串对象添加到字符串常量池中(如果池中不存在相同内容的字符串),并返回池中的字符串引用。为了深入理解它的实现原理,我们需要从 Java 层到 JVM 层逐步分析其工作机制。
1. Java 层的 String.intern()
方法
在 Java 标准库中,String.intern()
是一个本地方法(native
),其具体实现由 JVM 提供。它的作用是将当前字符串对象添加到字符串常量池中(如果池中不存在相同内容的字符串),并返回池中的字符串引用。方法定义如下:
2. JVM 层的 String.intern()
实现
当 Java 代码调用 String.intern()
时,JVM 会通过本地方法接口(JNI)调用 JVM 层的实现。
JNI 方法定义
JVM 需要在启动时注册 String.intern()
的本地方法实现。这个过程通常发生在 JVM 初始化阶段。
在 OpenJDK 源码中,String.intern()
的 JNI 方法定义位于 jvm.cpp
文件中:
JNI_ENTRY
和JNI_END
:这是 JNI 方法的宏定义,用于处理 JNI 调用时的环境设置和清理。jvm_intern
:这是String.intern()
的本地方法实现。JNIHandles::resolve_non_null
:将 Java 层的jstring
对象转换为 JVM 内部的oop
(普通对象指针)。StringTable::intern
:调用 JVM 内部的StringTable::intern()
方法,将字符串添加到字符串常量池中。
JNI 方法绑定
在 JVM 启动时,String.intern()
的本地方法实现会被绑定到 Java 层的 intern()
方法。这个过程是通过 JNIEnv::RegisterNatives
完成的。在 OpenJDK 源码中,String.intern()
的 JNI 方法绑定位于 SystemDictionary::initialize()
方法中:
JNINativeMethod
:这是一个结构体,用于描述本地方法的名称、签名和实现。RegisterNatives
:将 Java 层的intern()
方法与 JVM 层的jvm_intern()
实现绑定
StringTable::intern()
实现
当 JNI 调用 jvm_intern()
时,JVM 会进一步调用 StringTable::intern()
方法,完成字符串常量池的操作。
java_lang_String::as_unicode_string
:从oop
对象中提取字符串内容。java_lang_String::length
:获取字符串的长度。StringTable::intern
:调用内部的intern
方法,完成字符串常量池的操作。
详细内容请阅读https://xie.infoq.cn/article/be2da49fce15ad02f936c28e9
3. 实现原理总结
Java 代码调用 String.intern()
方法,由于 intern()
是一个 native
方法,调用会通过 JNI 传递到 JVM 层。JNI 层的 jvm_intern()
方法是 String.intern()
的具体实现。它负责将 Java 层的 jstring
对象转换为 JVM 内部的 oop
(普通对象指针),调用 StringTable::intern()
方法,完成字符串常量池的操作。StringTable::intern() 方法是 JVM 内部实现字符串常量池的核心方法。它的主要逻辑包括:计算哈希值、查找字符串常量池、插入字符串。
版权声明: 本文为 InfoQ 作者【储诚益】的原创文章。
原文链接:【http://xie.infoq.cn/article/631545e5ec45a3b0beebe481e】。文章转载请联系作者。
评论