字符串细微差别在Java中

时间:2014-08-10 06:02:07

标签: java

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作为输出?

我想知道在池区域中创建了哪个字符串,以及在池的非池区域中创建了哪个字符串。

3 个答案:

答案 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? 它还链接到一篇关于字符串实习的文章,这是一种只存储每个不同字符串的一个副本的机制。