【问题标题】:What is the meaning of a String ID in Java? [duplicate]Java中字符串ID的含义是什么? [复制]
【发布时间】:2012-10-25 07:43:30
【问题描述】:

可能重复:
why equals() method when we have == operator?

当我尝试在 Java 中执行代码时,它给了我 2 个不同的输出

String txt1="Hello";
String txt2="Hello";
System.out.println((boolean)txt1==txt2);

String txt1=new String("Hello");
String txt2=new String("Hello");
System.out.println((boolean)txt1==txt2);

【问题讨论】:

标签: java string


【解决方案1】:

== 运算符将检查引用是否相等,也就是说,如果两个参数 Strings 是同一个实例,则返回 true

每当String 字面量(例如"Hello")出现在一个类中时,String 实例就会被interned(一种存储在内部缓存中以便可以重复使用)。

在完成String txt1="Hello" 之后,txt1 将与实习生String 完全相同。所以,

String txt1="Hello";
String txt2="Hello";

导致txt1txt2 是同一个实例,即被实习的实例。

当您执行String txt1=new String("Hello") 时,它会调用String 构造函数,并将内部实例作为参数(一种复制构造函数)。因此,txt1 将是一个 String 实例,其值与实习实例相同,== 运算符将返回 false

可以在 JLS 的3.10.5. String Literals 部分找到有关该主题的更多信息。

字符串字面量是对 String 类实例的引用 (§4.3.1、§4.3.3)。

此外,字符串字面量总是指向同一个类的实例 细绳。这是因为字符串文字 - 或者更一般地说,字符串 这是常量表达式的值(第 15.28 节) - 是“interned” 以便使用 String.intern 方法共享唯一实例。

以下问题的答案解释When are Java Strings interned?。以下链接详细说明了该主题:String Equality and Interning

作为旁注,请记住使用equals() 以便根据其内容执行字符串比较。

【讨论】:

  • 当我尝试调试它们时,第二种情况下的 txt1 和 txt2 具有不同的 ID。那么这些ID是什么?它们是基于内存位置赋予对象的某种值吗?
  • 没错,就是标识实例的值。它们实际上是不同的 String 实例持有相同的值,所以 == 返回 false
【解决方案2】:

字符串是对象。 == 比较对象引用,而不是字符串的内容。为此,请使用String#equals 方法。

在您的第一个示例中,txt1txt2 是指向 相同 String 对象的两个变量。所以他们是==

在您的第二个示例中,txt1txt2 指向两个不同 String 对象(具有相同的字符序列),因此它们不是==彼此。


另外:写new String("string literal") 几乎没有任何意义。如果你不知道一个非常非常好的理由去做这件事,不要这样做。只有几个非常非常非常不寻常的情况你可能会这样做,这与与低级别的东西交互有关。不是普通的、可移植的 Java 代码。

偶尔有理由使用new String(String)(不是字符串文字,而是您从其他地方获得的实例,例如substring)。请参阅this article 了解更多信息(感谢Rp-)。

【讨论】:

  • 那为什么第一个返回true?
  • @user1247347:因为txt1txt2 是指向same 对象的变量。 (单击刷新以确保您正在阅读我的完整答案,我意识到我的第一个快速答案可能还不够并添加到其中。)
  • kjetilod.blogspot.in/2008/09/… 这个博客解释了new String(someStr);.. 的罕见用法。也请关注 cmets。
  • @MarkoTopolnik:确实,我已经澄清了。
  • @Rp-:谢谢你,非常有趣。
【解决方案3】:

这样做

String txt1="Hello";
String txt2="Hello";
System.out.println(txt1.hashCode());
System.out.println(txt2.hashCode());
System.out.println((boolean)txt1==txt2);


String txt1=new String("Hello");
String txt2=new String("Hello");
System.out.println(txt1.hashCode());
System.out.println(txt2.hashCode());
System.out.println((boolean)txt1==txt2);

您可以了解 java 内部如何处理。

【讨论】:

  • 这两种情况的 hashCode 是一样的!
  • @user1247347 是的。在这种情况下,可能是转换为文字的 String() 对象。当我们在运行时创建它时会得到不同的。
【解决方案4】:

Java 尽可能尝试将字符串“共享”到安全空间。

String txt1="Hello";
String txt2="Hello";

是对同一个对象的两个引用(“Hello”)

String txt1=new String("Hello");
String txt2=new String("Hello");

是对两个不同实例的两个引用,每个实例都由副本初始化。

如果比较字符串,请始终使用“equals()”,否则结果难以预测。

【讨论】:

    【解决方案5】:

    如果您想比较引用,请使用== 运算符。

    如果要比较两个字符串的内容,请使用equals 方法。

    【讨论】:

    • '==',而不是'='。 '=' 是一个任务
    • @thedayofcondor 感谢您的指点
    猜你喜欢
    • 2012-04-02
    • 2012-03-31
    • 2011-04-17
    • 2016-04-11
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    相关资源
    最近更新 更多