函数式接口egtoString、equals中继承对象类方法有什么用

Raj*_*j N 3 java inheritance object java-8 functional-interface

我找到了以下代码,继承的 equals() 和 toString() 方法的用途是什么。

@FunctionalInterface
public interface  FunInterface<T> {
   // An  abstract method  declared in the functional interface 
   int test(T  o1,   T  o2);

   // Re-declaration of the equals() method in the Object class 
   boolean equals(Object  obj);

   String toString();
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 7

(重新)声明这种方法的主要原因是扩展和记录合同。在 的情况下Comparator.equals(…),它不是那么明显,因为它没有指定太多新闻。它说

这种方法必须遵守 的一般契约Object.equals(Object)。此外,true 只有当指定的对象也是一个比较器并且它强制执行与此比较器相同的顺序时,此方法才能返回。因此,comp1.equals(comp2)意味着sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2))对于每个对象引用o1o2

大多数人无论如何都会假设的。更糟糕的equals是,如果不是说强制执行此合同的最佳方式,则不覆盖也很好,尤其是因为 JRE 类无论如何都不会考虑比较器相等性。

要获得更好的覆盖方法示例,请考虑

List.equals(Object)

返回true当且仅当指定对象也是一个列表,两个列表的大小相同,并且两个列表中所有对应的元素对都是equal。(两个元素e1并且e2相等,如果Objects.equals(e1, e2)。)

List.hashCode()

返回此列表的哈希码值。列表的哈希码定义为以下计算的结果:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
Run Code Online (Sandbox Code Playgroud)

这可确保list1.equals(list2)意味着list1.hashCode()==list2.hashCode()对于任何两个列表,list1list2根据需要通过的总承包合同Object.hashCode()

这提供了无法通过简单地使用继承自的equals(Object)hashCode()方法来实现的扩展契约java.lang.Object。不幸的是,接口不能强制其实现类覆盖这些方法,但这不应该阻止它声明它来记录合同。


当然,拥有这样的契约与使用接口作为功能接口的意图不兼容,因为 lambda 表达式和方法引用不能覆盖继承自的方法java.lang.Object以提供更具体的实现。

但是java.util.Comparator在 Java 2 中引入,早在 Java 8 之前,它引入了函数式接口的概念。如前所述,它的特殊之处在于我们仍然可以Comparator用作函数式接口,因为equals继承自的实现java.lang.Object对于为java.util.Comparator.equals.

因此,在设计用作函数式接口的新接口时,不应声明与java.lang.Object.