Singleton of Java functional interface as enum

Yeater :

While looking at the source code of the Comparators class, I came across these lines of code.

class Comparators {

    //...

    enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
        INSTANCE;

        @Override
        public int compare(Comparable<Object> c1, Comparable<Object> c2) {
            return c1.compareTo(c2);
        }

        @Override
        public Comparator<Comparable<Object>> reversed() {
            return Comparator.reverseOrder();
        }
    }

    //...

}

I think I understand what this does. It's a Singleton instance which implements the Comparator interface. It uses the "compareTo" of classes that implement the Comparable interface for natural ordering (please correct me if I am wrong in any of this).

What I do not understand however, why is it done using an enum. I really like enums for Singletons, don't get me wrong but in this case I personally think this would have been simpler:

public static final Comparator<Comparable<Object>> NATURAL_ORDER_COMPARATOR =
    new Comparator<Comparable<Object>>() {
        @Override
        public int compare(Comparable<Object> c1, Comparable<Object> c2) {
            return c1.compareTo(c2);
        }

        //...

    }

Are there any reasons to implement this using enums aside from personal preference?

Dean Xu :

It maybe due to Serializable.

Based on your approach, if you create an object that holds the Comparators.NATURAL_ORDER_COMPARATOR, when you write to the object and read it back, a new NATURAL_ORDER_COMPARATOR will be created. Since the object cost is so small it breaks the singleton.

Some evidence for that is Collections.ReverseComparator. It uses your approach:

static final ReverseComparator REVERSE_ORDER = new ReverseComparator();

But the drawback is that the following code must be present to maintain the singleton

private Object readResolve() { return Collections.reverseOrder(); }

Now which one is easier? Personally, I prefer to use 'enum singleton' pattern as my first choice.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=36076&siteId=1