Что такое перечисления и чем они полезны? - PullRequest
457 голосов
/ 17 января 2011

Сегодня я просматривал некоторые вопросы на этом сайте и обнаружил упоминание о enum , используемом в шаблоне синглтона , о предполагаемых преимуществах безопасности потоков для такого решения.Я никогда не использовал enum с, и я программирую на Java уже более пары лет.И, видимо, они сильно изменились.Теперь они даже полностью поддерживают ООП внутри себя.

Теперь, почему и зачем мне использовать enum в повседневном программировании?

Ответы [ 24 ]

8 голосов
/ 21 февраля 2013

Что такое перечисление

  • enum - это ключевое слово, определенное для перечисления нового типа данных. Типизированные перечисления должны использоваться свободно. В частности, они представляют собой надежную альтернативу простым константам String или int, используемым в гораздо более старых API для представления наборов связанных элементов.

Зачем использовать enum

  • перечисления неявно являются окончательными подклассами java.lang.Enum
  • если перечисление является членом класса, оно неявно статично
  • new никогда не может использоваться с перечислением, даже внутри самого перечисления
  • name и valueOf просто используют текст констант enum, тогда как toString может быть переопределен для предоставления любого содержимого, если это необходимо
  • для констант enum равны и == равны одному значению и могут использоваться взаимозаменяемо
  • константы перечисления неявно являются публичными static final

Примечание

  • перечисления не могут расширять любой класс.
  • Перечисление не может быть суперклассом.
  • порядок появления констант enum называется их «естественным порядком» и определяет порядок, используемый другими элементами: compareTo, порядок итераций значений, EnumSet, EnumSet.range.
  • Перечисление может иметь конструкторы, статические блоки и блоки экземпляров, переменные и методы, но не может иметь абстрактные методы.
6 голосов
/ 26 февраля 2013

Enum наследует все методы класса Object и абстрактного класса Enum. Таким образом, вы можете использовать его методы для отражения, многопоточности, сериализации, сопоставления и т. Д. Если вы просто объявите статическую константу вместо Enum, вы не сможете. Кроме того, значение Enum также может быть передано в слой DAO.

Вот пример программы для демонстрации.

public enum State {

    Start("1"),
    Wait("1"),
    Notify("2"),
    NotifyAll("3"),
    Run("4"),
    SystemInatilize("5"),
    VendorInatilize("6"),
    test,
    FrameworkInatilize("7");

    public static State getState(String value) {
        return State.Wait;
    }

    private String value;
    State test;

    private State(String value) {
        this.value = value;
    }

    private State() {
    }

    public String getValue() {
        return value;
    }

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public boolean isNotify() {
        return this.equals(Notify);
    }
}

public class EnumTest {

    State test;

    public void setCurrentState(State currentState) {
        test = currentState;
    }

    public State getCurrentState() {
        return test;
    }

    public static void main(String[] args) {
        System.out.println(State.test);
        System.out.println(State.FrameworkInatilize);
        EnumTest test=new EnumTest();
        test.setCurrentState(State.Notify);
        test. stateSwitch();
    }

    public void stateSwitch() {
        switch (getCurrentState()) {
        case Notify:
            System.out.println("Notify");
            System.out.println(test.isNotify());
            break;
        default:
            break;
        }
    }
}
4 голосов
/ 21 февраля 2013

ENum означает «Перечислимый тип».Это тип данных, имеющий фиксированный набор констант, которые вы определяете сами.

3 голосов
/ 25 февраля 2013

На мой взгляд, все ответы, которые вы получили до сих пор, верны, но по моему опыту я бы выразил это в нескольких словах:

Используйте перечисления, если вы хотите, чтобы компилятор проверил правильность значения идентификатора.

В противном случае вы можете использовать строки как обычно (возможно, вы определили некоторые «соглашения» для своего приложения), и вы будете очень гибкими ... но вы не получите 100% -ную защиту от опечаток в ваших строках, и реализовать их только во время выполнения.

3 голосов
/ 26 февраля 2013

Enum?Зачем его использовать?Я думаю, что это более понятно, когда вы будете его использовать.У меня такой же опыт.

Скажем, у вас есть операция создания, удаления, редактирования и чтения базы данных.

Теперь, если вы создаете enum как операцию:

public enum operation {
    create("1")
    delete("2")
    edit("3")
    read("4")

    // You may have is methods here
    public boolean isCreate() {
        return this.equals(create);
    }
    // More methods like the above can be written

}

Теперь вы можете объявить что-то вроде:

private operation currentOperation;

// And assign the value for it 
currentOperation = operation.create

Таким образом, вы можете использовать это разными способами.Всегда хорошо иметь enum для конкретных вещей, так как работой с базой данных в приведенном выше примере можно управлять, проверяя currentOperation .Возможно, можно сказать, что это может быть достигнуто с помощью переменных и целочисленных значений.Но я считаю, что Enum - более безопасный и программистский способ.

Другое дело: я думаю, что каждый программист любит boolean , не так ли?Потому что он может хранить только два значения, два конкретных значения.Таким образом, можно думать, что Enum имеет такой же тип средств, где пользователь будет определять, сколько и какой тип значения он будет хранить, просто немного по-другому.:)

2 голосов
/ 26 мая 2016

Java позволяет ограничить переменную одним из нескольких предопределенных значений - другими словами, одним значением из перечисляемого списка. Использование enums может помочь уменьшить количество ошибок в вашем коде. Вот пример enums вне класса:

enums coffeesize{BIG , HUGE , OVERWHELMING }; 
//This semicolon is optional.

Это ограничивает coffeesize наличием: BIG, HUGE или OVERWHELMING в качестве переменной.

2 голосов
/ 28 апреля 2015

Используйте перечисления для БЕЗОПАСНОСТИ ТИПА, это языковая функция, поэтому вы обычно получаете:

  • Поддержка компилятора (сразу см. Проблемы с типами)
  • Поддержка инструментов в IDE (автозаполнение в случае переключения ...)

У перечислений могут быть методы, конструкторы, вы даже можете использовать перечисления внутри перечислений и комбинировать перечисления с интерфейсами.

Думайте о перечислениях как о типах, заменяющих четко определенный набор int-констант (которые Java «унаследовала» от C / C ++).

Книга Effective Java 2nd Edition содержит целую главу о них и более подробно. Также смотрите этот пост переполнения стека .

1 голос
/ 28 мая 2017

Что касается меня, чтобы сделать код читаемым в будущем, то наиболее полезный и применимый случай перечисления представлен в следующем фрагменте:

public enum Items {
    MESSAGES, CHATS, CITY_ONLINE, FRIENDS, PROFILE, SETTINGS, PEOPLE_SEARCH, CREATE_CHAT
}

@Override
public boolean onCreateOptionsMenu(Menu menuPrm) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menuPrm);
    View itemChooserLcl;
    for (int i = 0; i < menuPrm.size(); i++) {
        MenuItem itemLcl  = menuPrm.getItem(i);
            itemChooserLcl = itemLcl.getActionView();
            if (itemChooserLcl != null) {
                 //here Im marking each View' tag by enume values:
                itemChooserLcl.setTag(Items.values()[i]);
                itemChooserLcl.setOnClickListener(drawerMenuListener);
            }
        }
    return true;
}
private View.OnClickListener drawerMenuListener=new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Items tagLcl= (Items) v.getTag();
        switch (tagLcl){
            case MESSAGES: ;
            break;
            case CHATS : ;
            break;
            case CITY_ONLINE : ;
            break;
            case FRIENDS : ;
            break;
            case  PROFILE: ;
            break;
            case  SETTINGS: ;
            break;
            case  PEOPLE_SEARCH: ;
            break;
            case  CREATE_CHAT: ;
            break;
        }
    }
};
1 голос
/ 16 декабря 2016

Что дало мне момент ах-ха, так это осознание: у Enum есть личный конструктор, доступный только через публичное перечисление:

enum RGB {
    RED("Red"), GREEN("Green"), BLUE("Blue");

    public static final String PREFIX = "color ";

    public String getRGBString() {
        return PREFIX + color;
    }

    String color;

    RGB(String color) {
        this.color = color;
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        String c = RGB.RED.getRGBString();
        System.out.print("Hello " + c);
    }
}
1 голос
/ 26 февраля 2013

Здесь много ответов, просто хочу указать два конкретных:

1) Использование в качестве константы в операторе Switch-case. Переключатель case не позволит вам использовать объекты String для case. Перечисления пригодятся. Подробнее: http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/

2) Реализация Singleton Design Pattern - Enum снова приходит на помощь. Использование здесь: Каков наилучший подход для использования Enum в качестве синглтона в Java?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...