Java中String字符串常量池和intern方法源码分析
什么是字符串常量池
在Java中,字符串是不可变的,也就是说,对一个字符串的任何操作都将返回一个新的字符串对象,而原来的字符串对象不会被修改。
为了提高String对象的创建和删除效率,Java引入了字符串常量池(String Pool),该池用来缓存字符串对象,可以减少新的String对象的创建数量以及对Java虚拟机内存的占用。
在Java中,运行时常量池是方法区(Method Area)的一部分,在类加载时被初始化,存储编译期生成的各种字面量和符号引用。
String类中intern方法
String类中有一个intern()方法,该方法是一个native方法,用于把String对象添加到字符串常量池中,如果字符串常量池中已经存在了该字符串,则返回常量池中的字符串对象,否则将该对象添加到字符串常量池中,并返回该对象的引用。
例如,假设现有一个字符串池:["abc", "def"],现在需要对字符串"abc"进行intern()操作,操作后返回的引用将是"abc"的地址,同时字符串池中的元素不变,仍然是["abc", "def"]。
intern方法源码分析
Java中String类的intern()方法的源码:
public native String intern();
从源码可以看出,String的intern()方法是一个native方法,也就是说该方法在Java程序之外的C++代码中被实现。在OpenJDK中,这个方法的本地实现大致如下:
static jstring string_pool::intern(Handle string_or_null, TRAPS) {
if (string_or_null() == NULL) {
// 如果字符串为null则返回null
return (jstring)string_or_null();
}
// 搜索常量池
StringTable* const pool = JvmtiExport::string_table();
Symbol* sym = NULL;
{
SharedStrings::LockGuard guard(pool->lock, true);
sym = pool->lookup_stage2(string_or_null, CHECK_NULL);
}
if (sym != NULL) {
// 字符串在常量池中存在
return (jstring)sym->ref_str();
} else {
// 添加到常量池
return pool->intern(string_or_null, CHECK_NULL);
}
}
可以看出,intern()方法的实现比较简单,就是在StringTable中查找该字符串,如果该字符串已经在其中,返回该字符串;否则,将其添加到StringTable并返回该字符串。
示例说明
下面是两个示例,说明了字符串常量池和intern()方法的使用:
示例一:
String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2); // true
// 以上代码中,str1和str2都指向字符串池中的"abc",因此相等。
String str3 = new String("abc");
System.out.println(str1 == str3.intern()); // true
// 以上代码中,str3.intern()将"abc"字符串添加到字符串池,并返回池中的字符串引用,
// 因此,str1和str3.intern()都指向字符串池中的"abc",因此相等。
示例二:
String str1 = new String("Hello");
String str2 = "Hello";
System.out.println(str1 == str2); // false
// 以上代码中,str1是用new创建的新的String对象,str2指向字符串池中的"Hello",
// 因此不相等。
String str3 = str1.intern();
String str4 = str2.intern();
System.out.println(str3 == str4); // true
// 以上代码中,str1.intern()将"Hello"添加到字符串池,并返回池中的字符串引用,
// str2.intern()直接返回字符串池中的"Hello",
// 因此str3和str4都指向字符串池中的"Hello",因此相等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中String字符串常量池和intern方法源码分析 - Python技术站