-1

首先,我在 SO 和 Google 中都搜索了这个。如果你说这是某处某物的复制品,那确实很难达到。

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

那么,请解释一下:

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"输出,为什么只有最后一个打印“真”?

当它们被创建时,它们不都是字符串吗?现在我的第三根弦是丑小鸭吗?...更糟糕的是:如果我正在使用外国字符串...它可能不是我认为的字符串?!(注意 s3String之前有,而不是一些原始的。)

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

换句话说,像这样声明 String 有什么区别:

String s1 = new String("string");

还有一个是这样的:

String s3 = "string";

?

4

4 回答 4

3

当你这样做时String s1 = new String("string");,它会在内存中创建一个新String对象并通过它来保存引用s1。类似String s2 = new String("string");地,您通过 获得另一个 String 对象引用s2

==运算符比较对象引用因此s1 == s2是错误的,因为它们是差异字​​符串对象。

当您说String s3 = "string";时,它会在内部池中创建一个String 常量文字 对象(String 类维护内部池)并将引用分配给s3.

以下规格中的更多详细信息:

所有文字字符串和字符串值的常量表达式都是实习的。字符串文字在Java 语言规范的 §3.10.5 中定义

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

情况并非如此,s1因为s2每个都引用内存中的显式 String 对象。

于 2012-12-02T17:43:44.353 回答
0

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

于 2012-12-02T18:01:27.627 回答
0

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

您的其他两个对象应该返回 true on equals(),但它们根本是不同的对象,因为您使用的是 new 运算符。

于 2012-12-02T17:41:43.220 回答
0

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

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

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

    System.out.println(s1 == s2);
于 2012-12-02T17:42:14.457 回答