字符串池是否存储文字或对象?

如何解决字符串池是否存储文字或对象?

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"是字符串文字。

对象是有用的抽象内存,用于存储有意义的数据位(当组合在一起时)表示某事的数据,无论是CarPerson还是{ {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;
}

http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/f3108e56b502/src/share/vm/classfile/symbolTable.cpp

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?