我无法识别以下Java中Strings声明的区别。
假设我有两个字符串
String str1="one";
String str2="two";
之间有什么区别
String str3=new String(str1+str2);
和
String str3=str1+str2;
在上述两个声明中,str3
的内容将为onetwo
。
假设我创建了一个新字符串
String str4="onetwo";
然后没有上述声明,
if(str4==str3) {
System.out.println("This is not executed");
}
为什么str3
和str4
没有引用同一个对象?
答案 0 :(得分:5)
str1 + str2
将被编译为
new StringBuilder(str1).append(str2).toString()
。这个结果不会被放入,也不会从字符串池中获取(其中有实际的字符串)。
在"foo"+"bar"
的情况下,编译器知道他使用哪些值,这是不同的故事,因此他可以将此字符串连接一次以在运行时避免它。这样的字符串文字也将被实习。
所以String str3 = str1+str2;
与
String str3 = new StringBuilder(str1).append(str2).toString();
和String str3 = new String(str1+str2);
与
String str3 = new String(new StringBuilder(str1).append(str2).toString());
同样,由方法产生的字符串(如substring
,replace
,toString
)不会被实习。
这意味着您要比较两个不同的实例(存储相同的字符),这就是==
返回false
的原因。
答案 1 :(得分:3)
Java没有“这个变量如何获得值”的记忆,因此如果结果相同,使用哪种方法并不重要。
关于比较,如果将字符串与==
进行比较,则需要比较内存中对象的地址,因为String不是原始数据类型,不是值。您必须使用if(str4.equals(str3))
答案 2 :(得分:3)
因为Java中的String
是不可变的,所以编译器将优化并重用String
文字。因此
String s1 = "one";
String s2 = "one";
s1 == s2; //true because the compiler will reuse the same String (with the same memory address) for the same string literal
s1 == "o" + "ne"; //true because "Strings computed by constant expressions are computed at compile time and then treated as if they were literals"
s3 = "o";
s1 == s3 + "ne"; //false because the second string is created a run time and is therefore newly created
有关参考资料,请参阅http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.5
答案 3 :(得分:0)
字符串有点棘手,因为有一些努力来分享他们的表示。而且他们是不可改变的。 简短的回答是:除非您真的处于较低级别,否则不应使用“==”比较字符串。 即使它对你有用,对你的队友来说也是一场噩梦。
要获得更长的答案和一点娱乐,请尝试以下方法:
String s1= "a" + "b";
String s2= "a" + "b";
String s3=new String("a"+"b");
System.out.println(s1==s2);
System.out.println(s3==s2);
由于编译器的共享努力,您会注意到s1 == s2。 但是s2!= s3因为你明确要求一个新的字符串。
,你不可能做任何非常聪明的事情,因为它是不可改变的。