Java: About ReverseComparator Collections Implementation

This is done as follows (jdk1.6.0_31):

private static class ReverseComparator<T> implements Comparator<Comparable<Object>>, Serializable { // use serialVersionUID from JDK 1.2.2 for interoperability private static final long serialVersionUID = 7207038068494060240L; public int compare(Comparable<Object> c1, Comparable<Object> c2) { return c2.compareTo(c1); } private Object readResolve() { return reverseOrder(); } } 

Why it cannot be implemented as follows:

 private static class ReverseComparator<T extends Comparable<T>> implements Comparator<T>, Serializable { // use serialVersionUID from JDK 1.2.2 for interoperability private static final long serialVersionUID = 7207038068494060240L; public int compare(T c1, T c2){ return c2.compareTo(c1); } ... } 

Is it just a style, or is there some deeper reason?

EDIT: shows source code from Sun / Oracle jdk ((jdk1.6.0_31)).

+6
source share
3 answers

I believe that all this is due to the intention of turning the ReverseComparator into a singlenton object. Since a singlenton instance must be defined in a static context, it makes no sense to use any generic types.

 static final ReverseComparator REVERSE_ORDER = new ReverseComparator(); 

This code generates a raw warning.

Thus, the implementation of ReverseComparator, which is used only for this, could be what you proposed or how it was implemented. Perhaps they chose the current implementation because it is easier to read, and because they thought that further generalization is not required if it is only private use for this simple purpose.

Running the Java decompiler on your implementation and on the Oracle implementation creates the same byte codes of the source type.

  public int compare(java.lang.Comparable, java.lang.Comparable public int compare(java.lang.Object, java.lang.Object); 

In the end, when the comparator is displayed through the public interface of the Collections class in the reverseOrder() method, casting and an unchecked warning cannot be avoided. But we are all sure that this cannot fail, regardless of the types used.

Bottom line, IMHO I think that the only reason it was implemented is due to the clarity of the code or the desire not to complicate things more than necessary if, in any case, an uncontrolled warning cannot be prevented. But hey, this is not the first time I am mistaken; -)

+1
source

Just guessing, but it is stored in a static field

 static final ReverseComparator REVERSE_ORDER = new ReverseComparator(); 

therefore, your version will generate a "raw types" warning.

+1
source

I look at Oracle 1.6.0_26, but I see the same code. As far as I can tell, they are functionally equivalent. You can also write this as follows:

 private static class ReverseComparator<T> implements Comparator<Comparable<T>>, Serializable { // use serialVersionUID from JDK 1.2.2 for interoperability private static final long serialVersionUID = 7207038068494060240L; public int compare( Comparable<T> c1, Comparable<T> c2 ) { return c2.compareTo( (T) c1 ); } private Object readResolve() { return reverseOrder(); } } 

My only suggestion about why they did this using Comparable<Object> is that classes that implement Comparable (or Comparator ) must obey the equals() contract that Object uses. Thus, semantically, this emphasizes this connection. Other than that, I can't figure out why.

+1
source

Source: https://habr.com/ru/post/914097/


All Articles