在Java中,当我们在创建字符串对象时使用文字字符串时,我知道在SCP(字符串常量池)中创建了一个新对象。
是否有办法检查变量在SCP还是堆中?
谢谢。
首先,正确的术语是“字符串池”,而不是“字符串常量池”;参见String pool - do String always exist in constant pool?
是否有办法检查变量在SCP还是堆中?
从Java 7和更高版本开始,字符串池位于(普通)堆中。因此,如果我们按字面意义进行解释,那么您的问题就没有意义了。
在Java 7之前,检查String
是否在字符串池中的方法是这样做
if (str == str.intern()) {
System.out.println("In the string pool");
}
但是,这存在一个问题,如果池中还没有等效的str
,您将向池中添加str
的副本。
从Java 7开始,上述测试不再可靠。 str.intern()
不再需要将字符串复制到单独的区域以将其添加为字符串池。因此,对实习生字符串的引用经常与对原始(非实习生)字符串的引用相同。
char[] chars = new char[]{'a', 'b', 'c'};
String str = new String(chars);
String interned = str.intern();
System.out.println(str == interned);
实际上,str == str.intern()
仅能检测到一个非中断字符串的内容与字符串文字相同的情况。
或至少列出SCP中的所有字符串实例?
没有办法做到这一点。
正如JB Nizet指出的那样,问这些问题确实没有多大意义:
intern
的级别,最好使用Java 9+垃圾收集器提供的机会字符串压缩机制。