【问题标题】:Understanding String and equals [duplicate]理解字符串和等于[重复]
【发布时间】:2013-08-26 16:06:22
【问题描述】:

使用String s1="java";String s2= new String("java"); 时 这两个都创建不同的字符串对象吗?我知道如果我使用 String s3="java" 它使用相同的对象 s1 但在 s2 情况下它是否也使用相同的对象?如果是这样,那么为什么StringBuffer sb = new StringBuffer("java"); 使用不同的对象。因为如果我这样做 System.out.println(sb.equals( s1 )); 它返回 false;

我对equals方法的理解是它比较两个引用是否引用同一个对象,除非我们重写了equals方法,如果我的理解有误,请告诉我。

【问题讨论】:

标签: java string


【解决方案1】:

好吧,我们打个比方。

如果我在两张纸上写下“HELLO”之类的同一个词。

然后我请来一个专家小组并问他们一些问题。

问。专家一。这两件事是一样的吗? A. 是的,它们是一样的,上面写着 HELLO。

问。专家二,用一张纸给我做一架纸飞机。 A. 好的,当然。

问。专家三,这两件事是一样的吗? A. 当然不是,一个是纸飞机。

问。专家四,再拿一张纸,在上面写上“你好”。现在这些东西都一样了吗?

A.当然,他们都说'HELLO'

所以,这取决于你所说的等号。

并且计算机语言有一些不直观的方式来定义等号。

有时等于意味着我们关心纸上的文字,有时我们担心它是完全相同的一张纸' 这在很多时候并不重要,只要它们都说“你好”

【讨论】:

  • 我认为当我们让你使用类比时我们犯了一个错误:-)
  • 恕我直言不是一个很好的类比...
【解决方案2】:

字符串 s1="java";和字符串 s2= new String("java");两者都做 这些创建不同的字符串对象

new 总是 创建一个新对象。也就是说,他们所指的内部字符串是相同的。在这种情况下,== 将返回 false,但 equals 将返回 true。

如果是这样,那么为什么 StringBuffer sb = new StringBuffer("java");采用 不同的对象

StringBuffer 不是String。他们是2个完全不同的班级。这与比较StringInteger 相同。也许你的意思是System.out.println(sb.toString().equals( s1 ));

我对 equals 方法的理解是,如果两者 除非我们重写了 equals 方法,否则引用引用相同的对象

您是对的,但在这种情况下,String 会覆盖 equals()(以及 hashcode()),因此行为与 Object#equals() 不同。

【讨论】:

    【解决方案3】:

    这两个是否创建不同的字符串对象

    这里有两个方面。第一个是字符串文字的实习。在这两个语句中:

    String s1 = "Hello";
    String s2 = new String("Hello");
    

    第一个将使用常量池中已经存在的文字字符串"Hello"。如果不存在,它将在常量池中为"Hello" 创建一个条目(在这种情况下,您可以说创建了一个对象)

    在第二种情况下,您有 2 个字符串对象 - 第一个是字符串文字 "Hello",它将从常量池中实习,然后第二个对象创建是由于使用了 new 关键字 - @ 987654329@ 肯定会创建一个新对象。所以:

    s1 == s2;  // This will return `false`
    

    因为 s1 和 s2 引用了 2 个不同的 String 对象。


    现在是你的第二个案例:

    String s1 = "Hello";
    StringBuffer sb = new StringBuffer("Hello");
    

    在第二条语句中,您正在创建一个新的 StringBuffer 对象。好吧,首先StringBuffer 不是String。其次,由于StringBuffer类没有覆盖equals()方法,所以当你像这样调用equals方法时:

    sb.equals(s1);
    

    它将调用Object#equals() 方法,该方法根据参考值进行比较。因此,它将返回 false,因为 sbs1 指向 2 个不同的实例。

    但是,如果你像这样比较它们:

    sb.toString().equals(s1);
    

    那么你现在会得到true。由于String 类重写了equals() 方法,该方法根据内容进行比较。


    另请参阅:

    【讨论】:

    • 一个小提示:StringBuffer 只使用Object equals 测试(即==)。它根本不会覆盖equals
    • +1 指出sb 不仅是一个不同的对象,而且是一个完全不同的类的实例。
    • @chrylis。是的,之前是一个小错误。已经编辑过了。谢谢:)
    【解决方案4】:
    String s1="java";
    

    此时,s1 指向一个String 对象。

    String s2 = new String("java");
    

    String 已经覆盖了equals 方法,以根据文档检查对象的内容。

    所以s1.equals(s2) 将评估为true,因为它们具有相同的内容。

    Object.equals() 会检查两个对象是否相同。

    【讨论】:

      【解决方案5】:

      你对equals方法的理解是错误的。是 == 运算符执行您所描述的操作。

      实现了 equal 方法(引用自 String 类文档):

      “当且仅当参数不为 null 并且是表示与此对象相同的字符序列的 String 对象时,结果才为真。”

      【讨论】:

      • Hmmm - "Object 类的 equals 方法实现了对象上最有区别的可能等价关系;也就是说,对于任何非空引用值 x 和 y,此方法返回当且仅当 x 和 y 引用同一个对象时才为真(x == y 的值为真)。”。您所说的仅适用于 String 类。
      【解决方案6】:

      s1 和 s3 引用同一个对象,但 s2 是内存中的另一个不同对象。查看http://www.journaldev.com/797/what-is-java-string-pool该链接上的图片和解释将比文字更清楚。

      【讨论】:

      • 感谢所有答案,但我仍然对究竟是什么方法让我们不限于 Stirng 类感到困惑;
      • @Anil equals 方法比较对象的内容。如果您了解对象引用,equals() 方法会比较对象的内容,但如果引用引用内存中的相同位置,则不会打扰。您可以像这样创建相同的引用:String str1=new String("Cat")String str2=str1 在这种情况下,str1.equals(str2) 方法将始终返回 truestr1==str1。但是当两个字符串都被创建并且它们的内容 (表示被引用的值) 不同时,equals() 方法将返回 false
      猜你喜欢
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      相关资源
      最近更新 更多