如何解决字符串池是否存储文字或对象?
Stackoverflow 充满了与不同类型的String初始化相关的问题。我了解String s = "word"
与String s = new String("word")
有何不同。因此,无需“触摸”该主题。
我注意到有不同的人提到String池存储常量/对象/文字。
常量是可以理解的,因为它们是最终的,因此它们总是“呆在”那里。是的,重复项也不会存储在 SCP 中。
但是我不知道 SCP 是否存储对象或文字。它们是完全不同的概念。 对象是实体,而文字是只是一个值。那么正确的答案是什么。 SCP 是否存储对象或文字?我知道不能同时都是:)
解决方法
严格来说,“文字”不是值;它是一种语法形式。 Java中的String文字是双引号,后跟一些非双引号(或转义的双引号)字符,并以另一个双引号结尾。 “文字值”是根据源代码文字创建的值,而不是诸如a.concat(b)
之类的评估值。核心区别在于字面值可以在编译时识别,而评估值只能在执行期间知道。这允许编译器将文字值存储在已编译的字节码内。 (由于编译器在编译时也知道由文字值初始化的常量,因此也可以在编译时计算仅使用常量的求值。)
在口语演讲中,人们可以将文字值称为“文字”,但这可能是造成混淆的原因-值就是值,无论其来源是文字还是评估。
我知道不能同时存在
文字值和评估值之间的区别与对象值和原始值之间的区别是分开的。 "foo"
是文字字符串值(由于字符串是对象,因此它也是一个对象)。 3
是文字原语(整数)值。如果x
当前为7
,则18 - x
的计算结果为非文字原始值11
。如果y
当前为"world!"
,则"Hello," + y
的计算结果为非文字,非原始值"Hello,world!"
。
文字是一大堆由"
分隔的源代码。例如,在下面的源代码行中:
String s = "Hello World";
"Hello World"
是字符串文字。
对象是有用的抽象内存,用于存储有意义的数据位(当组合在一起时)表示某事的数据,无论是Car
,Person
还是{ {1}}。
字符串池存储String
对象而不是String
文字,这是因为字符串池不存储源代码。
您可能会听到人们说“字符串池存储字符串文字”。它们(可能)并不意味着字符串池以某种方式在其中包含源代码String
。它们(可能)意味着源代码中由字符串文字表示的所有"Hello World"
都将放入字符串池中。实际上,由源代码中的常量表达式产生的String
也会自动添加到字符串池中。
好问题。可以通过如何实现String :: intern()来找到答案。来自javadoc:
* When the intern method is invoked,if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method,then the string from the pool is
* returned. Otherwise,this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
* <p>
因此字符串池存储字符串对象。
我们可以打开源代码来确认答案。 String :: intern()是本机方法,它在StringTable :: intern(),symbolTable.hpp
中定义oop StringTable::intern(Handle string_or_null,jchar* name,int len,TRAPS) {
unsigned int hashValue = hash_string(name,len);
int index = the_table()->hash_to_index(hashValue);
oop found_string = the_table()->lookup(index,name,len,hashValue);
// Found
if (found_string != NULL) {
ensure_string_alive(found_string);
return found_string;
}
... ...
Handle string;
// try to reuse the string if possible
if (!string_or_null.is_null()) {
string = string_or_null;
} else {
string = java_lang_String::create_from_unicode(name,CHECK_NULL);
}
... ...
// Grab the StringTable_lock before getting the_table() because it could
// change at safepoint.
oop added_or_found;
{
MutexLocker ml(StringTable_lock,THREAD);
// Otherwise,add to symbol to table
added_or_found = the_table()->basic_add(index,string,hashValue,CHECK_NULL);
}
ensure_string_alive(added_or_found);
return added_or_found;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。