Каков наилучший подход для использования Enum в качестве синглтона в Java?

85

Основываясь на том, что было написано в вопросе SO Лучшая реализация синглтона в Java, а именно об использовании перечисления для создания синглтона - каковы различия / плюсы / минусы между (конструктор опущен)

public enum Elvis {
    INSTANCE;
    private int age;

    public int getAge() {
        return age;
    }
}

а затем позвонив Elvis.INSTANCE.getAge()

а также

public enum Elvis {
    INSTANCE;
    private int age;

    public static int getAge() {
        return INSTANCE.age;
    }
}

а затем позвонив Elvis.getAge()

Майлз Д
источник

Ответы:

96

Предположим, вы привязываетесь к чему-то, что будет использовать свойства любого данного объекта - вы можете очень легко передать Elvis.INSTANCE, но вы не можете передать Elvis.class и ожидать, что он найдет свойство (если только он не закодирован специально для поиска статические свойства классов).

В основном вы используете шаблон singleton только тогда, когда вам нужен экземпляр. Если вам подходят статические методы, просто используйте их и не беспокойтесь о перечислении.

Джон Скит
источник
1
Почему бы не заняться перечислением? Есть ли лучший способ делать сингелтоны в java5 +?
jontro
4
@jontro (повторно) прочтите ответ; он говорит использовать перечисления, когда у вас должен быть синглтон, но избегать синглтона, если вы можете обойтись статическими методами
Miserable Variable
@MiserableVariable Я прокомментировал это больше года назад. Не могу вспомнить, о каком контексте я имел в виду.
jontro
не отвечает на заданный вопрос
Туфир 02
2
@Thufir: он отвечает на часть «в чем разница», которая, по-видимому, была тем, что больше всего интересовало ОП, учитывая, что ответ был принят.
Джон Скит,
69

Большое преимущество - это когда ваш синглтон должен реализовывать интерфейс. Следуя вашему примеру:

public enum Elvis implements HasAge {
    INSTANCE;
    private int age;

    @Override
    public int getAge() {
        return age;
    }
}

С участием:

public interface HasAge {
    public int getAge();
}

Со статикой этого не сделать ...

Николас
источник
1
Это можно сделать с помощью статики ... public static final HasAge INSTANCE = new HasAge () {private int age; @Override public int getAge () {вернуть возраст; }}; ... так что мне все еще интересно, что хорошего или лучшего в методе enum. Я полагаю, если вам нужно было реализовать два интерфейса?
Шон Адкинсон
9

(Stateful) Синглтоны обычно используются для того, чтобы делать вид, что не используют статические переменные. Если вы на самом деле не используете общедоступную статическую переменную, вы обманете меньше людей.

Том Хотин - tackline
источник
8

Я бы выбрал самый простой и понятный вариант. Это несколько субъективно, но если вы не знаете, что является наиболее ясным, выберите самый короткий вариант.

Питер Лоури
источник