我对字符串池实际包含的内容有点困惑。
当我们说String s = "abc"
时,这是否意味着在编译期间,字符串对象被放入字符串池中,还是被放入的引用?
字符串池只是字符串文字的缓存。每当我们将字符串文字分配给字符串引用时,都会在字符串池中搜索文字并将其分配给引用变量。在String s="abc"
JVM 中,将"abc"
在字符串池中搜索文字并将其引用分配给引用变量s
。
____________
refers | |
String s ------->| abc |<---- String Pool
|___________|
如果字符串常量池不存在,该语句String s = "abc"
会导致在字符串常量池中创建它。abc
如果存在,则将返回一个引用。你可以在这里找到关于字符串常量池的很好的教程。
http://www.thejavageek.com/2013/06/19/the-string-constant-pool/
每次以这种方式创建 String 时,JVM 都会检查此 Object 是否在 String 常量池中。如果是这样,将返回对“池化”实例的引用。如果没有,则初始化一个新实例并将其放入池中:
----------- String s = "Hello";
|
٧
+-------------------+
| "Hello" |
+-------------------+
pool
“abc”是在编译时在这里定义的,因此会被自动实习。因此,该字符串对象将进入字符串实习池。如果其中已经存在,则将返回其引用。字符串实习生池是 Java 7 以来主 Java 堆的一部分(我们知道堆将包含对象)。
您正在谈论的池位于堆中,并且存在的所有引用都存在于堆栈(而不是堆)上。当您创建字符串时,String s = "abc";
字符串文字“abc”被放置在字符串池中,并且所有进一步的引用都将指向该文字,除非您使用 new 创建字符串对象(在这种情况下,在堆上分配了单独的内存空间) .
字符串池是指内存中定义字符串的地方。字符串池具有对要重用的常量的引用。字符串池是允许这种情况发生的原因:
String a = "a" + "b";
String b = "ab";
if(a == b) {
System.out.println("this will print");
}
a==b 将评估为真,因为编译器认为字符串 a 和字符串 b 都等于“ab”,因此该字符串存储在字符串池中,并且字符串 a 和字符串 b 都指向这个引用。