Java中字符串池的底层机制?
问题内容:
我很好奇,为什么字符串可以在不调用创建new String()
,作为API提到它是Object
的class
java.lang.String
那么我们怎么能使用String s="hi"
而不是String s=new String("hi")
呢?
这篇文章阐明了利用==
运营商和缺乏new
,并说这是由于String
被文字 拘留 或由文字池拍摄JVM
的,因此Strings
是不可变的。
在看到诸如
String s="hi"
第一次 真正发生了什么?
-
是否
JVM
像这样替换它String s=new String("hi")
,其中创建了一个对象并将"hi"
其添加到 String文字池 ,因此随后的调用(例如String s1="hi"
从池中进行)? -
这是底层机制的运作方式吗?如果是这样,那么是
String s=new String("Test");
String s1=”Test”;
与…相同
String s="Test";
String s1="Test";
在内存利用率和 效率方面 ?
- 另外,是否可以通过任何方式访问字符串池以检查其中
String
存在多少文字,占用了多少空间等?
问题答案:
String s="hi"
第一次真正发生了什么?
JVM是否像这样替换它
String s=new String("hi")
,其中创建了一个对象并将“
hi”添加到String文字池,因此从该池中获取了诸如String s1 =“ hi”之类的后续调用?
否。真正发生的是- 字符串字面 量在编译时 解析 ,并在类被 加载/初始化 或 延迟 时进行 嵌入
(添加到String常量池中)。因此,它们可用于JVM中的类。请注意,即使您在Strings常量池中有一个带有value 的String,也会在堆上
创建 另一个String并返回其引用。 "hi"``new String("hi")
__
- 是
String s=new String("Test");
String s1="Test";
与…相同
String s="Test";
String s1="Test";
在内存利用率和效率方面?
否,在第一种情况下,将创建2个“测试”字符串。一个将被添加到String常量池中(假设它在那里不存在),另一个将被添加到堆中。第二个可以被GCed。在第二种情况下,字符串常量池中仅存在一个字符串
文字 ,并且有2个对它的引用(s
和s1
)。
- 另外,如果有什么方法可以访问字符串池,例如检查程序或任何监视工具中存在多少字符串文字,占用的空间等?
我认为我们看不到String常量池的内容。我们只能根据我们的假设来 假设 并 确认 行为。