Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the use of inheriting object class methods in functional interface eg- toString, equals

I found following code, What is use of inherited equals() and toString() method.

@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();
}
like image 315
Raj N Avatar asked Oct 18 '25 14:10

Raj N


1 Answers

The main reason to (re)declare such a method, is to extend and document the contract. In case of Comparator.equals(…), it’s not that obvious, as it doesn’t specify so much news. It says

This method must obey the general contract of Object.equals(Object). Additionally, this method can return true only if the specified object is also a comparator and it imposes the same ordering as this comparator. Thus, comp1.equals(comp2) implies that sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2)) for every object reference o1 and o2.

which most people would have assumed anyway. Even worse, not overriding equals is fine, if not to say the best way to enforce this contract, especially as the JRE classes never consider comparator equality anyway.

To get better examples of overriding methods, consider

List.equals(Object)

Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal. (Two elements e1 and e2 are equal if Objects.equals(e1, e2).)

List.hashCode()

Returns the hash code value for this list. The hash code of a list is defined to be the result of the following calculation:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

This ensures that list1.equals(list2) implies that list1.hashCode()==list2.hashCode() for any two lists, list1 and list2, as required by the general contract of Object.hashCode().

This provides an extended contract that can not be fulfilled by simply using the equals(Object) and hashCode() methods inherited from java.lang.Object. Unfortunately, an interface can not enforce its implementation classes to override these methods, but that shouldn’t stop it from declaring it to document the contract.


Of course, having such a contract would not be compatible with an intention of using an interface as functional interface, as lambda expressions and method references can not override methods inherited from java.lang.Object to provide more specific implementations.

But java.util.Comparator was introduced in Java 2, long before Java 8, which introduced the concept of functional interfaces. As said, it’s special in that we still can use Comparator as functional interface, as the equals implementation inherited from java.lang.Object is fine regarding the contract specified for java.util.Comparator.equals.

So when designing new interfaces intended to be used as functional interface, you should not declare methods matching those of java.lang.Object.

like image 151
Holger Avatar answered Oct 21 '25 03:10

Holger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!