关于 Java 字符串池的问题
2022-08-31 13:59:52
请考虑以下代码:
String first = "abc";
String second = new String("abc");
使用关键字时,Java会再次创建对吗?这是存储在常规堆上还是池中?池中将结束多少秒?new
abc
String
String
String
String
请考虑以下代码:
String first = "abc";
String second = new String("abc");
使用关键字时,Java会再次创建对吗?这是存储在常规堆上还是池中?池中将结束多少秒?new
abc
String
String
String
String
如果使用关键字,将创建一个新对象。请注意,对象始终位于堆上 - 字符串池不是独立于堆的单独内存区域。new
String
字符串池就像一个缓存。如果这样做:
String s = "abc";
String p = "abc";
然后Java编译器足够聪明,可以只创建一个对象,并且两者都引用相同的String对象。如果这样做:String
s
p
String s = new String("abc");
然后池中将有一个对象,表示文本的对象,并且将有一个单独的对象,不在池中,其中包含池中对象内容的副本。由于在Java中是不可变的,因此这样做不会获得任何好处;调用在Java中永远没有意义,并且不必要的低效。String
"abc"
String
String
new String("literal")
请注意,您可以调用对象。如果对象尚不存在,这会将该对象放入池中,并返回对池化字符串的引用。(如果它已经在池中,它只返回对已经存在的对象的引用)。有关详细信息,请参阅该方法的 API 文档。intern()
String
String
另见字符串实习(维基百科)。
在字节码中,第一个赋值为:
Code: 0: ldc #2; //String abc 2: astore_1
而第二个是:
3: new #3; //class java/lang/String 6: dup 7: ldc #2; //String abc 9: invokespecial #4; //Method java/lang/String."":(Ljava/lang/String;)V
因此,第一个位于池中(位于位置 #2),而第二个将存储在堆中。
编辑
由于将索引存储为 U2(16 位,无符号),因此池可以包含 max = 引用。如果您在这里关心JVM的更多限制。CONSTANT_String_info
2**16
65535