Java 字符串常量池、新对象初始化(使用新关键字)与字符串的正常初始化?
在Java 字符串常量池、新对象初始化(使用新关键字)与字符串的正常初始化?,java,string,Java,String,在s1中,将创建两个对象,一个在字符串池中,另一个在非池内存中 在s2中,字符串池中将只创建一个对象 如果我们这样做: String s1 = new String("abc"); String s2 = "abc"; 现在字符串池中有3个对象(“abc”,“def”,和“abcdef”),其中两个被放弃(“def”和“abcdef”),将“abc”留在内存中 两个引用都引用了字符串池对象 记忆对象的意义是什么?和s2.concat(“def”)发生在运行时,它们不会成为常量池的一部分,而是进
s1
中,将创建两个对象,一个在字符串池中,另一个在非池内存中
在s2
中,字符串池中将只创建一个对象
如果我们这样做:
String s1 = new String("abc");
String s2 = "abc";
现在字符串池中有3个对象(“abc”
,“def”
,和“abcdef”
),其中两个被放弃(“def”
和“abcdef”
),将“abc”
留在内存中
两个引用都引用了字符串池对象
记忆对象的意义是什么?和s2.concat(“def”)代码>发生在运行时,它们不会成为常量池的一部分,而是进入堆
注意concat
的签名:
s1.concat("def");
s2.concat("def");
它返回一个新字符串,并且您没有将该字符串分配给任何变量
记忆对象的意义是什么
不清楚您在问什么,但请注意,由于未分配由concat
创建的字符串(对它的引用将被丢弃),因此它有资格进行垃圾收集
在s2
中,字符串池中将只创建一个对象
实际上不,这条线不会创建新对象s2
将引用用于构造s1
的同一常数
现在字符串池中有3个对象(“abc”
,“def”
,和“abcdef”
),其中两个被放弃(“def”
和“abcdef”
),将“abc”
留在内存中
不,只有“abc”
和“def”
在常量池中,由于它们是常量,因此在程序运行期间将保留在内存中<代码>“abcdef”
在构建后将立即被垃圾收集,因为它从未存储在任何地方
如果您使用了+
操作符而不是String.concat()
,编译器实际上会将两个常量字符串合并为一个,并且只将结果字符串存储在池中
两个引用都引用了字符串池对象
否,只有s2
引用常量池中的字符串,并且.concat()
的结果都不会在常量池中
记忆对象的意义是什么
您是否在问字符串常量池的意义是什么?它本质上只是一种允许常量的优化(例如,“
-ed字符串在代码中)共享同一引用以避免构造多个相同的实例。因为它们是常量,所以可以在编译时执行此操作,从而在运行时节省空间和时间。除非显式调用,否则这不适用于在运行时构造的任何字符串,但通常应这样做
您也可能对以下内容感兴趣:
编辑:由于您坚持您的示例中的
“abcdef”
将是常量池的一部分,这里有一个简单的证据证明情况并非如此:
public String concat(String str)
$javac-version
JavaC1.7.0_02
$cat Test.java
公开课考试{
公共静态void main(字符串[]args){
字符串s1=“123”+“456”;
字符串s2=“abc”。concat(“def”);
}
}
$javac Test.java
$javap-c-classpath.Test
从“Test.java”编译而来
公开课考试{
公开考试();
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:ldc#2//字符串123456
2:astore_1
3:ldc#3//字符串abc
5:ldc#4//字符串定义
7:invokevirtual#5//方法java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String;
10:astore_2
11:返回
}
您可以清楚地看到,字符串
123456
、abc
和def
都是常量(请参阅),并且String.concat()
在运行时被调用。您认为“内存对象的意义是什么?”?为什么您认为“abcdef”会出现在字符串池中?还有,“abcdef”将成为垃圾收集的候选对象,因为您没有将concat()的结果分配给任何变量。concat()不修改字符串。它创造了一个新的世界。@PurvenderHooda你似乎确信你比这里的每个人都了解。那你为什么要问?不,s1.concat(“def”)的结果不会进入字符串池。我不明白你在问我什么。@PurvenderHooda-我不是说字符串literal“abcdef”
。我说的是由s1.concat(“def”)
生成的字符串abcdef
。我向您保证,它不会进入字符串常量池。它们将是字符串常量池的一部分。我们没有赋值,问题是对象的总数以及它们在哪个内存中的位置。请注意,在给定的上下文中,abc
,def
,123456
是类常量,而不是字符串常量池的常量。i、 e,类常数!=字符串常量池(不总是)
$ javac -version
javac 1.7.0_02
$ cat Test.java
public class Test {
public static void main(String[] args) {
String s1 = "123" + "456";
String s2 = "abc".concat("def");
}
}
$ javac Test.java
$ javap -c -classpath . Test
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String 123456
2: astore_1
3: ldc #3 // String abc
5: ldc #4 // String def
7: invokevirtual #5 // Method java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String;
10: astore_2
11: return
}