public class StringTest {
public static void main(String[] args) {
String s1 = "java";
String s2 = "ja" + "va";
String s3 = "ja";
String s4 = s3 + "va";
System.out.println(s1 == s2);
System.out.println(s1 == s4);
}
}
首先 System.out.println(...); 语句作为预期输出为true,但为什么第二个语句显示为false作为输出?
我想知道在池区域中创建了哪个字符串,以及在池的非池区域中创建了哪个字符串。
答案 0 :(得分:1)
使用.equals()
来比较String
个对象。
{
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s4));
}
这是因为==
上的Object
运算符(此处为String
)会检查相同的对象引用,因为您必须使用String
等式.equals()
。
+
连接运算符从以下位置有效编译:
a + b (a, b type String)
为:
new StringBuffer(a).append(b) (loading String in the common pool)
另一方面,在以下代码中:
String s1 = "java";
String s2 = "ja" + "va";
// "ja" appends to "va". As the compiler optimization pass realizes
// that "ja" + "va" is literal "java", it burns down the two strings into
// the same literal as s1.
String s3 = "ja";
String s4 = s3 + "va";
// s3 appends to "va". As the compiler cannot effectively study the literal,
// It is allowed to be concatenated at run-time. This allows "java" to be
// created from the heap, instead of from the common pool.
答案 1 :(得分:1)
Java中的字符串文字被嵌入(放入缓存的字符串池中)。文字就是当它们纯粹在代码中用“”编写时。
当在编译时可以计算字符串文字的整个表达式(在你的情况下是连接)时,这样的字符串也会被实现。
您实习生"java"
和"ja"
。编译器可能足够聪明,可以看到s3在声明+初始化之间没有变化,但它没有,因为它不是最终的。
将s3
声明为final
将为第二个SOP生效。因此,在打印前添加s4 = s4.intern();
。
编辑:你问“究竟是什么是s4 = s4.intern()”:
s4.intern()将查看缓存字符串池,并将缓存的equal
字符串从池中返回到s4。然后再次分配给s4。所以:它将s4引用替换为缓存版本(如果存在)。 [Sideeffect:如果它不在池中,它将被添加并且引用不变]。
答案 2 :(得分:0)
==
测试引用相等,而.equals()
测试值相等。
只有在保证同时使用同一个对象时才使用==
。
有关详细信息:How do I compare strings in Java? 它还链接到一篇关于字符串实习的文章,这是一种只存储每个不同字符串的一个副本的机制。