单例的Java功能接口为枚举

Yea*_*ter 13 java singleton enums design-patterns

在查看Comparators类的源代码时,我遇到了这些代码行.

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();
        }
    }

    //...

}
Run Code Online (Sandbox Code Playgroud)

我想我明白这是做什么的.它是一个实现Comparator接口的Singleton实例.它使用实现Comparable接口的类的"compareTo"进行自然排序(如果我错了,请纠正我).

然而,我不明白为什么使用枚举完成它.我真的很喜欢Singletons的枚举,不要误会我的意思但在这种情况下我个人认为这会更简单:

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);
        }

        //...

    }
Run Code Online (Sandbox Code Playgroud)

除了个人偏好之外,还有任何理由使用枚举来实现吗?

Dea*_* Xu 15

这可能是由于Serializable.

根据您的方法,如果您创建一个包含该对象的对象Comparators.NATURAL_ORDER_COMPARATOR,当您写入该对象并将其读回时,NATURAL_ORDER_COMPARATOR将创建一个新对象.由于对象成本太小,因此打破了单例.

一些证据就是这样Collections.ReverseComparator.它使用您的方法:

static final ReverseComparator REVERSE_ORDER = new ReverseComparator();
Run Code Online (Sandbox Code Playgroud)

但缺点是必须存在以下代码才能维护单例

private Object readResolve() { return Collections.reverseOrder(); }
Run Code Online (Sandbox Code Playgroud)

现在哪一个更容易?就个人而言,我更喜欢使用'enum singleton'模式作为我的首选.


Eug*_*ene 6

这正是第89项中的要点:对于实例控制,实际上更喜欢枚举类型来自Effective Java的readResolve,它与之有关Serialization.

保持readResolve代替枚举实例要复杂得多且繁琐.