and*_*and 68 java string string-pool
考虑以下代码:
String first = "abc";
String second = new String("abc");
Run Code Online (Sandbox Code Playgroud)
使用new关键字时,Java会abc String再次创建吗?这会存储在常规堆还是String池中?多少人String在将s结尾String池?
Jes*_*per 95
如果使用new关键字,String将创建一个新对象.请注意,对象始终位于堆上 - 字符串池不是与堆分离的单独内存区域.
字符串池就像一个缓存.如果你这样做:
String s = "abc";
String p = "abc";
Run Code Online (Sandbox Code Playgroud)
那么Java编译器足够聪明,使只有一个String对象,s并且p将两者指的是同一个String对象.如果你这样做:
String s = new String("abc");
Run Code Online (Sandbox Code Playgroud)
然后String池中将有一个对象,即表示文字的对象"abc",并且将有一个单独的String对象,而不是池中的对象,它包含池化对象内容的副本.因为String在Java中是不可变的,所以你不会通过这样做获得任何东西; 调用new String("literal")在Java中永远不会有意义,并且不必要地低效.
请注意,您可以调用intern()一个上String对象.这将把String对象放入池中(如果它尚不存在),并返回对池化字符串的引用.(如果它已经在池中,它只返回对已存在的对象的引用).有关详细信息,请参阅该方法的API文档.
另见String interning(维基百科).
dfa*_*dfa 12
在字节码中,第一个赋值是:
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位置),而第二个将存储在堆中.
编辑
由于将CONSTANT_String_info 索引存储为U2(16位,无符号),因此池可以包含max 2**16= 65535references.在这种情况下,您关心JVM的更多限制.
每次代码创建一个字符串文字
例如:
String str="Hello"; (string literal)
Run Code Online (Sandbox Code Playgroud)
JVM首先检查字符串文字池.如果池中已存在该字符串,则返回对池化实例的引用.如果池中不存在该字符串,则新的String对象将实例化,然后放入池中.Java可以进行此优化,因为字符串是不可变的,可以共享而不用担心数据损坏
| 归档时间: |
|
| 查看次数: |
23006 次 |
| 最近记录: |