当我学习 java.lang.String Java API 时,这个问题就出现了。
我找到了一篇中文文章。Java 中new String("字面量") 中 "字面量" 是何时进入字符串常量池的? https://www.zhihu.com/question/55994121/answer/147296098
it said,CONSTANT_String
在 HotSpot VM 中是惰性解析,因此 String Literal 被加载到 StringTable util 中使用。
我发现了一些相关的说法。
jvms 第 5.4 章。链接 http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4 says
例如,Java 虚拟机实现可以选择在使用时单独解析类或接口中的每个符号引用(“惰性”或“延迟”解析),或者在验证类时一次性解析所有符号引用( “热切”或“静态”解决方案)。
我找到了一些openjdk代码ldc
IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide))
// access constant pool
constantPoolOop pool = method(thread)->constants();
int index = wide ? get_index_u2(thread, Bytecodes::_ldc_w) :get_index_u1(thread, Bytecodes::_ldc);
constantTag tag = pool->tag_at(index);
if (tag.is_unresolved_klass() || tag.is_klass()) {
klassOop klass = pool->klass_at(index, CHECK);
oop java_class = klass->java_mirror();
thread->set_vm_result(java_class);
} else {
#ifdef ASSERT
// If we entered this runtime routine, we believed the tag contained
// an unresolved string, an unresolved class or a resolved class.
// However, another thread could have resolved the unresolved string
// or class by the time we go there.
assert(tag.is_unresolved_string()|| tag.is_string(), "expected string");
#endif
oop s_oop = pool->string_at(index, CHECK);
thread->set_vm_result(s_oop);
}
IRT_END
以及关于 pool->string_at(index, CHECK) 的代码
oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
oop str = NULL;
CPSlot entry = this_oop->slot_at(which);
if (entry.is_metadata()) {
ObjectLocker ol(this_oop, THREAD);
if (this_oop->tag_at(which).is_unresolved_string()) {
// Intern string
Symbol* sym = this_oop->unresolved_string_at(which);
str = StringTable::intern(sym, CHECK_(constantPoolOop(NULL)));
this_oop->string_at_put(which, str);
} else {
// Another thread beat us and interned string, read string from constant pool
str = this_oop->resolved_string_at(which);
}
} else {
str = entry.get_oop();
}
assert(java_lang_String::is_instance(str), "must be string");
return str;
}
But
这些代码只能证明 String Literal 可能已加载到 StringTable util 中ldc
,但无法证明 HotSpot VM 中的延迟解析。
有人可以明确解释一下吗。
仅供参考,我懂一点c,但不懂c++。
Thanks.!