由于创建不同,字符串的行为会有所不同吗?

时间:2012-12-02 17:37:00

标签: java string comparison equals

首先,我在S.O.中搜索了这个。和谷歌。如果你说这是某个地方的重复,那就很难达到。

嗯......我们知道字符串是对象,必须使用equals进行比较,对吗?

然后,请解释一下:

String s1 = new String("string");
String s2 = new String("string");
String s3 = "string";

System.out.println(s1.equals(s2));  // true
System.out.println(s1 == s2);       // false

System.out.println(s1 == "string"); // false
System.out.println(s2 == "string"); // false
System.out.println(s3 == "string"); // true

关于== "string"输出,为什么只有最后一个输出“true”?

当它们被创建时,它们不是所有字符串?现在我的第三个串丑小鸭? ...更糟糕的是:如果我正在使用外来字符串...它可能不是我认为的字符串?! (请注意,s3之前有String,而不是某些原语。)

......我很确定s3里面有一个对象。

换句话说,声明像这样的字符串之间的区别是什么:

String s1 = new String("string");

和另一个像这样:

String s3 = "string";

4 个答案:

答案 0 :(得分:3)

执行String s1 = new String("string");时,它会在内存中创建一个新的String对象,并通过s1保存引用。与String s2 = new String("string");类似,您可以通过s2获得另一个String对象引用。

==运算符会比较对象引用,因此s1 == s2为false,因为它们是不同的字符串对象。

当您说String s3 = "string";时,它会在内部池中创建一个 String constant literal 对象( String类维护内部池)并将引用分配给{{ 1}}。

以下规范中的更多细节:

  
    

所有文字字符串和字符串值常量表达式都被实现。字符串文字在Java Language Specification

的§3.10.5中定义   

现在,当您说s3时,s3=="string"引用与"string"相同的String对象引用(Java在创建匿名常量文字时进行优化,因此不再创建相同的值文字)。因此,这种比较导致s3

trues1不是这种情况,因为每个都在内存中引用显式的String对象。

答案 1 :(得分:0)

编译器将搜索像“string”这样的硬编码文字,并用相同的参考对象替换它们。

你的另外两个对象应该在equals()上返回true,但它们根本就是不同的对象,因为你正在使用new运算符。

答案 2 :(得分:0)

String类型的某些值可以 interned ,也就是说,具有相同值的String的多个实例可以指向同一个对象。对于此类实例,==将正常工作,但您不能依赖此行为,除非您明确调用intern()

您可以尝试以下代码段,该代码段将始终打印true

    String s1 = new String("a").intern();
    String s2 = "a".intern();

    System.out.println(s1 == s2);

答案 3 :(得分:0)

我希望你知道java中的SCP(字符串常量池)。当你使用new创建字符串时,它将像普通的java对象一样创建新的引用...但是当你声明像s3 =“string”时,它将在SCP中仅为相同的值字符串创建一次引用。这意味着如果你创建任何其他像s5 =“字符串”它将指向相同的引用,它不会创建新的引用。 ==将仅检查引用但.equals()方法检查值。在你的程序“字符串”字符串值已经存储在scp区域,所以当你检查s3 ==“string”时它返回true。它没有创造新的参考。如果你想要更多的clarety帖子评论...