首先,我在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";
答案 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
。
true
和s1
不是这种情况,因为每个都在内存中引用显式的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帖子评论...