在Java中使用带有String和Object的equals()方法

Object o1 = new Object(); Object o2 = new Object(); //o1=o2; System.out.println(o1.equals(o2)); 

它返回false 。 如果删除注释,它可以返回true


为什么不适用于String类?

 String s1=new String(); String s2=new String(); System.out.println(s1.equals(s2)); 

它返回true 。 为什么? (因为String使用实习或其他涉及的东西?)

因为String的equals()比较内容,而不是对象本身。

public boolean equals(Object anObject)

将此字符串与指定的对象进行比较。 当且仅当参数不为null并且是表示与此对象相同的字符序列的String对象时,结果才为真。

  /* String.equals() */ public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; } 

(链接到String.equals()的源代码)

对象相等

Object的equals方法实现了Object上最具辨别力的等价关系; 也就是说,对于任何非空引用值xy ,当且仅当xy引用同一对象时,此方法才返回true( x == y的值为true )。

 /* Object.equals() */ public boolean equals(Object obj) { return (this == obj); } 

(链接到Object.equals()的源代码)

另外,不要忘记equals()函数的契约:

equals方法在非null对象引用上实现等价关系:

  • 它是自反的 :对于任何非空引用值xx.equals(x)应该返回true。
  • 它是对称的 :对于任何非空引用值xy ,当且仅当y.equals(x)返回true时, x.equals(y)应返回true。
  • 它是传递性的 :对于任何非空引用值xyz ,如果x.equals(y)返回truey.equals(z)返回true ,则x.equals(z)应返回true
  • 它是一致的 :对于任何非空引用值xyx.equals(y)多次调用始终返回true或始终返回false ,前提是没有修改对象的equals比较中使用的信息。
  • 对于任何非空引用值xx.equals(null)应返回false

还建议阅读:

  • 是Object.hashCode()
  • 有效的Java(布洛赫)

equals for Object比较内存引用。
这就是为什么它是错误的,因为它们是不同的Object
重写String equals基于字符进行比较。
你有2个空的String对象,这就是equals返回true

==比较对象/字符串/任何东西的地址

.equals()旨在使用对象的内部状态进行比较。

所以:

new Object() == new Object() => false – 内存中不同地址的两个独立对象。

new String("a") == new String("a") => false – 相同的情况 – 字符串对象的两个单独地址。

new String("a").equals(new String("a")) => true – 地址不同,但Java将采用一个对象状态(’a’)并与其他对象状态(’a’)进行比较他们平等,并将报告真实。

使用equals()方法,您可以以任何适合您的程序的方式编写比较代码。

intern()是一个有点不同的故事。 它旨在为相同的char序列返回相同的对象(地址)。 当您多次构造相同的字符串时,减少所需的内存量非常有用。

new String("aaa").intern()将在机器内存中查找是否有人在之前创建了“aaa”字符串并将返回字符串的第一个实例…如果找不到,则将使用当前的实例作为第一个和所有进一步的“aaa”.intern()和新的String("aaa").intern()("a"+"aa").intern()将返回该“第一个”实例。

注意: "aaa".intern()操作速度不是很快,如果你将实习所有的字符串 – 你将节省一些内存,但会耗费相当多的CPU工作。

Object类中实现的equals仅比较引用。 这是源代码:

 public boolean equals(Object obj) { return (this == obj); } 

如果你想让它以某种其他方式运行,则需要在类中重写equals方法。 默认情况下,它会检查两个引用是否引用同一对象。

Object类的equals()方法不知道如何比较Strings,它只知道如何比较对象。 为了比较字符串,字符串类将覆盖equals()方法并比较其中的字符串。

Object.equals()将仅比较引用,其中String.equals()将比较值。