Czym są enums i dlaczego są przydatne?

Dzisiaj przeglądałem kilka pytań na tej stronie i znalazłem wzmiankę o enum stosowany w singletonie wzór o rzekomych korzyściach bezpieczeństwa wątku dla takiego rozwiązania.

Nigdy nie używałem enum s I programuję w Javie od ponad kilku lat. I najwyraźniej bardzo się zmieniły. Teraz nawet robią pełne wsparcie OOP w sobie.

Dlaczego I do czego powinienem używać enum w codziennym programowaniu?

 412
Author: James P., 2011-01-17

23 answers

Należy zawsze używać enums, gdy zmienna (zwłaszcza parametr metody) może przyjąć tylko jedną z małych wartości. Przykładami mogą być stałe typu (status kontraktu: "permanent"," temp", "apprentice") lub flagi ("execute now","defer execution").

Jeśli używasz enums zamiast liczb całkowitych( lub łańcuchów znaków), zwiększasz sprawdzanie w czasie kompilacji i unikasz błędów związanych z przekazywaniem nieprawidłowych stałych, a także dokumentujesz, które wartości są legalne użyj.

BTW, nadużywanie enum może oznaczać, że Twoje metody robią za dużo (często lepiej mieć kilka oddzielnych metod, a nie jedną, która pobiera kilka flag, które modyfikują to, co robi), ale jeśli musisz użyć FLAG lub wpisać kody, enums są dobrym rozwiązaniem.

Jako przykład, który jest lepszy?

/** Counts number of foobangs.
 * @param type Type of foobangs to count. Can be 1=green foobangs,
 * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
 * @return number of foobangs of type
 */
public int countFoobangs(int type)

Kontra

/** Types of foobangs. */
public enum FB_TYPE {
 GREEN, WRINKLED, SWEET, 
 /** special type for all types combined */
 ALL;
}

/** Counts number of foobangs.
 * @param type Type of foobangs to count
 * @return number of foobangs of type
 */
public int countFoobangs(FB_TYPE type)

Wywołanie metody jak:

int sweetFoobangCount = countFoobangs(3);

Następnie staje się:

int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);

W drugim przykładzie od razu wiadomo, które typy są dozwolone, dokumenty i implementacja nie mogą zostać zsynchronizowane, a kompilator może to wymusić. Również niepoprawne wywołanie jak

int sweetFoobangCount = countFoobangs(99);

Nie jest już możliwe.

 547
Author: sleske,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-13 16:54:17

Po co używać funkcji języka programowania? Powodem, dla którego w ogóle mamy Języki, jest

  1. Programiści efektywnie i poprawnie wyrażają algorytmy w formie, z której mogą korzystać Komputery.
  2. opiekunowie do zrozumienia algorytmów napisanych przez innych i poprawnie wprowadzają zmiany.

Liczby poprawiają zarówno prawdopodobieństwo poprawności, jak i czytelność bez pisania dużej ilości kotłów. Jeśli jesteś chętny do napisania boilerplate, to możesz "symulować" liczby:

public class Color {
    private Color() {} // Prevent others from making colors.
    public static final Color RED = new Color();
    public static final Color AMBER = new Color();
    public static final Color GREEN = new Color();
}

Teraz możesz napisać:

Color trafficLightColor = Color.RED;

Powyższa Płyta kotła ma taki sam efekt jak

public enum Color { RED, AMBER, GREEN };

Oba zapewniają ten sam poziom pomocy w sprawdzaniu przez kompilator. Boilerplate jest po prostu bardziej typowania. Ale zapisywanie dużej ilości wpisów sprawia, że programista jest bardziej wydajny (Patrz 1), więc jest to funkcja warta zachodu.

Warto to zrobić z jeszcze jednego powodu:]}

Switch statements

Jedna rzecz, którą static final powyższa symulacja enumeratywna nie daje Ci ładne switch przypadki. W przypadku typów enum Przełącznik Java używa typu swojej zmiennej, aby wywnioskować zakres przypadków enum, więc dla enum Color powyżej wystarczy powiedzieć:

Color color = ... ;
switch (color) {
    case RED:
        ...
        break;
}

Uwaga to nie Color.RED w przypadkach. Jeśli nie używasz enum, jedynym sposobem na użycie nazwanych ilości z switch jest coś w stylu:

public Class Color {
    public static final int RED = 0;
    public static final int AMBER = 1;
    public static final int GREEN = 2;
}

Ale teraz zmienna do przechowywania koloru musi mieć typ int. Ładny kompilator sprawdzający enum i static final symulacja przepadła. Nie jestem szczęśliwy.

Kompromisem jest użycie skalarnego członu w symulacji:

public class Color {
    public static final int RED_TAG = 1;
    public static final int AMBER_TAG = 2;
    public static final int GREEN_TAG = 3;

    public final int tag;

    private Color(int tag) { this.tag = tag; } 
    public static final Color RED = new Color(RED_TAG);
    public static final Color AMBER = new Color(AMBER_TAG);
    public static final Color GREEN = new Color(GREEN_TAG);
}

Teraz:

Color color = ... ;
switch (color.tag) {
    case Color.RED_TAG:
        ...
        break;
}
[[29]} ale uwaga, jeszcze więcej kotła!

Użycie enum jako singleton

Z kotłowni powyżej możesz zobaczyć, dlaczego enum zapewnia sposób implementacji Singletona. Zamiast pisać:

public class SingletonClass {
    public static final void INSTANCE = new SingletonClass();
    private SingletonClass() {}

    // all the methods and instance data for the class here
}

A następnie dostęp do niego za pomocą

SingletonClass.INSTANCE

Możemy po prostu powiedzieć

public enum SingletonClass {
    INSTANCE;

    // all the methods and instance data for the class here
}

Co daje nam to samo. Możemy to ujść na sucho, ponieważ enumery Javy zaimplementowane jako pełne klasy z odrobiną cukru składniowego posypanego na wierzchu. To znowu mniej boilerplate, ale to nieoczywiste, chyba że idiom jest ci znajomy. Nie podoba mi się również fakt, że dostajesz różne funkcje enum, mimo że nie mają one większego sensu dla singletonu: ord i values, itp. (W rzeczywistości istnieje trudniejsza symulacja, w której Color extends Integer będzie działać z przełącznikiem, ale jest tak tricky, że jeszcze wyraźniej pokazuje, dlaczego enum jest lepszym pomysłem.)

Zabezpieczenie gwintu

Bezpieczeństwo nici jest potencjalnym problemem tylko wtedy, gdy singletony są tworzone leniwie bez blokowania.

public class SingletonClass {
    private static SingletonClass INSTANCE;
    private SingletonClass() {}
    public SingletonClass getInstance() {
        if (INSTANCE == null) INSTANCE = new SingletonClass();
        return INSTANCE;
    }

    // all the methods and instance data for the class here
}

Jeśli wiele wątków wywołuje getInstance jednocześnie, gdy INSTANCE jest nadal null, można utworzyć dowolną liczbę instancji. Jest źle. Jedynym rozwiązaniem jest dodanie synchronized dostępu w celu ochrony zmiennej INSTANCE.

Jednakże powyższy kod static final nie ma tego problem. Tworzy instancję chętnie w czasie ładowania klasy. Ładowanie klas jest zsynchronizowane.

Singleton jest efektywnie leniwy, ponieważ nie jest inicjowany przed pierwszym użyciem. Inicjalizacja Javy jest również zsynchronizowana, więc wiele wątków nie może zainicjować więcej niż jednej instancji INSTANCE. Dostajesz leniwie zainicjowany singleton z bardzo małym kodem. Jedynym minusem jest raczej niejasna składnia. Musisz znać idiom lub dokładnie zrozumieć, w jaki sposób Klasa ładowanie i inicjalizacja pracy, aby wiedzieć, co się dzieje.

 122
Author: Gene,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-18 00:39:56

Poza wspomnianymi już przypadkami użycia, często uważam enums za przydatny do implementacji wzorca strategii, stosując się do kilku podstawowych wytycznych OOP:

  1. o kodzie, w którym znajdują się dane (tj. wewnątrz samego enum - lub często wewnątrz stałych enum, które mogą nadpisywać metody).
  2. Implementowanie interfejsu (lub więcej), aby nie wiązać kodu klienta z enum (które powinno dostarczać tylko zestaw domyślnych implementacji).

Najprostszy przykład będzie zbiorem Comparator implementacji:

enum StringComparator implements Comparator<String> {
    NATURAL {
        @Override
        public int compare(String s1, String s2) {
            return s1.compareTo(s2);
        }
    },
    REVERSE {
        @Override
        public int compare(String s1, String s2) {
            return NATURAL.compare(s2, s1);
        }
    },
    LENGTH {
        @Override
        public int compare(String s1, String s2) {
            return new Integer(s1.length()).compareTo(s2.length());
        }
    };
}

Ten "wzorzec" może być używany w znacznie bardziej złożonych scenariuszach, wykorzystując w szerokim zakresie wszystkie dobrodziejstwa, które są dostarczane z enum: iteracja instancji, poleganie na ich ukrytej kolejności, pobieranie instancji po jej nazwie, statyczne metody zapewniające właściwą instancję dla określonych kontekstów itp. I nadal masz to wszystko ukryte za interfejsem, więc Twój kod będzie działał z niestandardowymi implementacjami bez modyfikacji w przypadku, gdy chcesz coś, co nie jest dostępne wśród "opcji domyślnych".

Widziałem to z powodzeniem stosowane do modelowania pojęcia ziarnistości czasu (dzienne, tygodniowe, itp.), gdzie cała logika została zamknięta w enum (wybór odpowiedniej ziarnistości dla danego zakresu czasowego, specyficzne zachowanie związane z każdą ziarnistością jako metody stałe itp.). Mimo to, Granularity widziany przez warstwę usług był po prostu interfejsem.

 37
Author: Costi Ciudatu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-14 09:36:55

Coś, czego żadna z innych odpowiedzi nie obejmowała, co czyni enums szczególnie potężnymi, to możliwość posiadaniametod szablonowych . Metody mogą być częścią base enum i nadpisywane przez każdy typ. Z zachowaniem dołączonym do enum, często eliminuje to potrzebę konstrukcji if-else lub instrukcji switch, ponieważ ten post na blogu pokazuje - gdzie enum.method() robi to, co pierwotnie byłoby wykonane wewnątrz warunkowego. Ten sam przykład pokazuje również zastosowanie statycznych importuje z enums, a także produkuje znacznie czystszy kod podobny do DSL.

Inne ciekawe cechy to fakt, że enums zapewnia implementację dla equals(), toString() i hashCode() oraz zaimplementować Serializable i Comparable.

Aby uzyskać kompletny przegląd wszystkich enums, Gorąco polecam Bruce ' a Eckela Thinking in Java 4th edition , który poświęca cały rozdział temu tematowi. Szczególnie pouczające są przykłady dotyczące kamienia, papieru, nożyczek (tj. RoShamBo) gra jako enums.
 32
Author: orangepips,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-17 03:49:28

From Java documents-

Powinieneś używać typów enum w każdej chwili potrzeba reprezentowania stałego zbioru stałe. W tym naturalne enum typy takie jak planety w naszym słońcu systemy i zbiory danych, w których znasz wszystkie możliwe wartości przy kompilacji czasu-np. wybory na menu, flagi linii poleceń i tak dalej.

Powszechnym przykładem jest zastąpienie klasy zestawem prywatnych statycznych końcowych stałych int (w rozsądnej liczbie stałe) z typem enum. Zasadniczo, jeśli wydaje ci się, że znasz wszystkie możliwe wartości "czegoś" w czasie kompilacji, możesz reprezentować to jako typ enum. Enum zapewnia czytelność i elastyczność w stosunku do klasy ze stałymi.

Kilka innych zalet, które mogę wymyślić typy enum. Są zawsze jedną z instancji danej klasy enum (stąd pojawia się koncepcja używania enum jako singleton). Kolejną zaletą jest możliwość użycia enums jako typu w instrukcji switch-case. Możesz również użyć toString () na enum, aby wydrukować je jako czytelne ciągi znaków.

 20
Author: CoolBeans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-17 01:43:13

Teraz dlaczego I do czego powinienem użyć enum w codziennym programowaniu?

Możesz użyć Enum, aby reprezentować mały stały zbiór stałych lub wewnętrzny tryb klasy przy jednoczesnym zwiększeniu czytelności. Również Enums może wymusić pewną sztywność, gdy jest używany w parametrach metody. Oferują ciekawą możliwość przekazania informacji konstruktorowi, jak w przykładzie planet na stronie Oracle i, jak już odkryłeś, pozwalają również w prosty sposób stworzyć wzór Singletona.

Ex: Locale.setDefault(Locale.US) czyta lepiej niż Locale.setDefault(1) i wymusza użycie stałego zestawu wartości pokazanych w IDE, gdy dodasz separator . zamiast wszystkich liczb całkowitych.

 17
Author: James P.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-30 16:30:47

Enums wylicza stały zbiór wartości, w sposób samodokumentujący.
Sprawiają, że kod jest bardziej wyraźny, a także mniej podatny na błędy.

Dlaczego nie używać String lub int zamiast Enum dla stałych?

  1. kompilator nie dopuszcza literówek , ani wartości poza ustaloną zbiór, jako że liczby są typami same w sobie. Konsekwencje:
    • nie będziesz musiał pisać warunku wstępnego (lub instrukcji if), Aby upewnić się, że twój argument jest w poprawny zakres.
    • typ niezmienny przychodzi za darmo.
  2. Enums może mieć zachowanie, tak jak każda inna klasa.
  3. prawdopodobnie potrzebujesz podobnej ilości pamięci, aby użyć Strings, w każdym razie (zależy to od złożoności Enum).

Ponadto, każda z instancji Enum jest klasą, dla której można zdefiniować jej indywidualne zachowanie.

Dodatkowo zapewniają bezpieczeństwo wątku Po utworzeniu instancji (gdy enum jest załadowane), który widział wielkie zastosowanie w uproszczeniu Singleton wzór .

Ten blog ilustruje niektóre jego zastosowania, takie jak Maszyna stanowa dla parsera.

 11
Author: afsantos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-25 19:25:01

Warto wiedzieć, że enums są tak samo jak inne klasy z polami Constant i private constructor.

Na przykład,

public enum Weekday
{
  MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
} 

Kompilator kompiluje go w następujący sposób;

class Weekday extends Enum
{
  public static final Weekday MONDAY  = new Weekday( "MONDAY",   0 );
  public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 );
  public static final Weekday WEDNESDAY= new Weekday( "WEDNESDAY", 2 );
  public static final Weekday THURSDAY= new Weekday( "THURSDAY", 3 );
  public static final Weekday FRIDAY= new Weekday( "FRIDAY", 4 );
  public static final Weekday SATURDAY= new Weekday( "SATURDAY", 5 );
  public static final Weekday SUNDAY= new Weekday( "SUNDAY", 6 );

  private Weekday( String s, int i )
  {
    super( s, i );
  }

  // other methods...
}
 9
Author: Ad Infinitum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-27 11:23:30

enum oznacza enum eracja tzn. wzmianka (kilka rzeczy) jeden po drugim.

An enum jest typem danych, który zawiera stały zestaw stałych.

Lub

enum jest podobnie jak class, ze stałym zestawem instancji znanych w czasie kompilacji.

Na przykład:

public class EnumExample {
    interface SeasonInt {
        String seasonDuration();
    }

    private enum Season implements SeasonInt {
        // except the enum constants remaining code looks same as class
        // enum constants are implicitly public static final we have used all caps to specify them like Constants in Java
        WINTER(88, "DEC - FEB"), SPRING(92, "MAR - JUN"), SUMMER(91, "JUN - AUG"), FALL(90, "SEP - NOV");

        private int days;
        private String months;

        Season(int days, String months) { // note: constructor is by default private 
            this.days = days;
            this.months = months;
        }

        @Override
        public String seasonDuration() {
            return this+" -> "+this.days + "days,   " + this.months+" months";
        }

    }
    public static void main(String[] args) {
        System.out.println(Season.SPRING.seasonDuration());
        for (Season season : Season.values()){
            System.out.println(season.seasonDuration());
        }

    }
}

Zalety enum:

  • enum poprawia bezpieczeństwo typu podczas sprawdzania kompilacji, aby uniknąć błędów w czas trwania.
  • enum może być łatwo użyty w przełączniku
  • enum można przechodzić
  • enum może mieć pola, konstruktory i metody
  • Enum może zaimplementować wiele interfejsów, ale nie może rozszerzyć żadnej klasy, ponieważ wewnętrznie rozszerza klasę Enum]}

Dla więcej

 8
Author: Premraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-05 01:50:15

Poza wszystkim, co mówili inni.. W starszym projekcie, w którym pracowałem, wiele komunikacji między podmiotami (niezależnymi aplikacjami) było za pomocą liczb całkowitych, które reprezentowały mały zestaw. Warto było zadeklarować zbiór jako enum statycznymi metodami, aby uzyskać enum obiekt z value i viceversa. Kod wyglądał na czystszy, przełączył się na użyteczność i łatwiejsze pisanie do logów.

enum ProtocolType {
    TCP_IP (1, "Transmission Control Protocol"), 
    IP (2, "Internet Protocol"), 
    UDP (3, "User Datagram Protocol");

    public int code;
    public String name;

    private ProtocolType(int code, String name) {
        this.code = code;
        this.name = name;
    }

    public static ProtocolType fromInt(int code) {
    switch(code) {
    case 1:
        return TCP_IP;
    case 2:
        return IP;
    case 3:
        return UDP;
    }

    // we had some exception handling for this
    // as the contract for these was between 2 independent applications
    // liable to change between versions (mostly adding new stuff)
    // but keeping it simple here.
    return null;
    }
}

Utwórz obiekt enum z odebranych wartości (np.]} Zapis do logów za pomocą myEnumObj.name

Mam nadzieję, że to pomoże.
 7
Author: sErVerdevIL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-25 12:21:27

Co to jest enum

  • enum jest słowem kluczowym zdefiniowanym dla Wyliczenia nowego typu danych. Typesafe wyliczenia powinny być stosowane obficie. W szczególności są solidną alternatywą dla prostych ciągów znaków lub stałych int używanych w znacznie starszych interfejsach API do reprezentowania zestawów powiązanych elementów.

Dlaczego używać enum

  • enums są w domyśle ostatecznymi podklasami Javy.lang.Enum
  • Jeśli enum jest członkiem klasy, jest niejawnie statyczne
  • nowe nigdy nie mogą być używane z enum, nawet w obrębie samego typu enum
  • name i valueOf po prostu używają tekstu stałych enum, podczas gdy toString może zostać nadpisany, aby w razie potrzeby podać dowolną treść
  • dla stałych enum, jest równa i = = jest równa tej samej rzeczy i może być używana zamiennie
  • stałe enum są domyślnie public static final

Uwaga

  • enums nie może rozszerzyć żadnej klasy.
  • enum nie może być klasą nadrzędną.
  • kolejność pojawienia się stałe enum nazywa się ich "porządkiem naturalnym" i definiuje kolejność używaną przez inne elementy: compareTo, iteracyjny porządek wartości, EnumSet, EnumSet.zasięg.
  • Wyliczenie może mieć konstruktory, statyczne i instancyjne bloki, zmienne i metody, ale nie może mieć metod abstrakcyjnych.
 7
Author: tinker_fairy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-30 16:59:35

Enum dziedziczy wszystkie metody klasy Object i klasy abstrakcyjnej Enum. Możesz więc użyć jego metod do refleksji, wielowątkowości,serializacji, porównywalnych itp. Jeśli zadeklarujesz tylko stałą statyczną zamiast Enum, nie możesz. poza tym, wartość Enum może być również przekazana do warstwy DAO.

Oto przykładowy program do zademonstrowania.
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;
        }
    }
}
 6
Author: abishkar bhattarai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-16 20:50:36

Enum oznacza "typ wyliczeniowy". Jest to typ danych mający stały zestaw stałych, które sam definiujesz.

 4
Author: Steve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-21 12:51:09

Moim zdaniem wszystkie odpowiedzi jakie otrzymałeś do tej pory są aktualne, ale z mojego doświadczenia chciałbym to wyrazić w kilku słowach:

Użyj enums, jeśli chcesz, aby kompilator sprawdzał poprawność wartości identyfikatora.

W przeciwnym razie możesz używać ciągów znaków tak jak zawsze (prawdopodobnie zdefiniowałeś jakieś "konwencje" dla swojej aplikacji) i będziesz bardzo elastyczny... ale nie otrzymasz 100% bezpieczeństwa przed literówkami na ciągach i zrealizujesz je tylko w czasie wykonywania.

 3
Author: Rafa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-25 14:22:48

Enum? Dlaczego warto go stosować? Myślę, że jest bardziej zrozumiałe, kiedy będziesz go używać. Mam to samo doświadczenie.

Powiedzmy, że masz operację tworzenia, usuwania, edycji i odczytu bazy danych.

Teraz jeśli utworzysz enum jako operację:

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

}

Teraz możesz zadeklarować coś w stylu:

private operation currentOperation;

// And assign the value for it 
currentOperation = operation.create
Więc możesz go używać na wiele sposobów. Zawsze dobrze jest mieć enum dla konkretnych rzeczy, ponieważ operacja bazy danych w powyższym przykładzie może być kontrolowana przez sprawdzenie currentOperation . Być może można powiedzieć, że można to osiągnąć za pomocą zmiennych i wartości całkowitych. Ale uważam, że Enum jest bezpieczniejszy i bardziej programistyczny.

Inna sprawa: myślę, że każdy programista kocha boolean , prawda? Ponieważ może przechowywać tylko dwie wartości, dwie konkretne wartości. Tak więc Enum może być postrzegane jako posiadanie tego samego typu obiektów, w których użytkownik zdefiniuje ile i jaki rodzaj wartości będzie przechowywał, tylko w nieco inny sposób. :)

 3
Author: Abhishek Bhandari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-30 16:30:09

Java pozwala ograniczyć zmienną do jednej z kilku predefiniowanych wartości - innymi słowy, jednej wartości z listy wyliczonej. Użycie enums może pomóc zmniejszyć liczbę błędów w kodzie. Oto przykład enums poza klasą:

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

Ogranicza to coffeesize do posiadania albo: BIG , HUGE , lub OVERWHELMING jako zmienna.

 2
Author: Rahul Prajapat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-26 02:17:47

Do tej pory nigdy nie musiałem używać enum. Czytam o nich, ponieważ zostały one wprowadzone w wersji 1.5 lub tiger, jak to było nazywane z powrotem w dzień. Nigdy nie rozwiązali dla mnie "problemu". Dla tych, którzy go używają (a widzę, że wielu z nich to robi), jestem pewien, że na pewno służy jakiś Cel. Tylko moje 2 funty.

 1
Author: happybuddha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-25 22:57:49

Jest tu wiele odpowiedzi, chcę tylko wskazać dwie konkretne:

1) Używanie jako stałych w instrukcji Switch-case. Przełącznik case nie pozwala na używanie obiektów String dla case. Wyliczenia się przydają. Więcej: http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/

2) Implementing Singleton Design Pattern - Enum ponownie, przychodzi na ratunek. Użycie, tutaj: Jakie jest najlepsze podejście do używania Enum jako Singletona w Javie?

 1
Author: Vishal Verma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:33

To, co dało mi moment Ah-Ha, to uświadomienie sobie, że Enum ma prywatny konstruktor dostępny tylko poprzez publiczne wyliczenie:

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
Author: djangofan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-02 20:28:29

Jak dla mnie aby Kod był czytelny w przyszłości najbardziej użyteczny przypadek wyliczenia jest przedstawiony w następnym fragmencie:

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
Author: CodeToLife,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-28 18:43:45

Użyj enums dla bezpieczeństwa typu, jest to funkcja językowa, więc zwykle otrzymasz:

  • Wsparcie kompilatora (od razu zobacz problemy z typem)
  • wsparcie narzędzi w IDE (automatyczne uzupełnianie w przypadku przełącznika ...)

Enums może mieć metody, konstruktory, można nawet używać enums wewnątrz enums i łączyć enums z interfejsami.

Pomyśl o enumach jako typach zastępujących dobrze zdefiniowany zestaw stałych int (które Java 'odziedziczyła' po C/C++).

Książka skuteczna Java 2nd Edition zawiera cały rozdział o nich i zawiera więcej szczegółów. Zobacz również ten post przepełnienia stosu .

 1
Author: Christophe Roussy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-08 23:41:24

Z mojego doświadczenia wynika, że użycie Enum czasami powoduje, że systemy są bardzo trudne do zmiany. Jeśli używasz Enum dla zestawu wartości specyficznych dla danej domeny, które często się zmieniają, i ma on wiele innych klas i komponentów, które od niego zależą, możesz rozważyć użycie , a nie.

Na przykład system handlu, który używa Enum dla rynków/giełd. Istnieje wiele rynków i jest prawie pewne, że będzie wiele podsystemów które muszą uzyskać dostęp do tej listy rynków. Za każdym razem, gdy chcesz dodać nowy rynek do swojego systemu lub jeśli chcesz go usunąć, możliwe, że wszystko pod słońcem będzie musiało zostać przebudowane i wydane.

Lepszym przykładem może być coś w rodzaju kategorii produktu. Załóżmy, że Twoje oprogramowanie zarządza zapasami dla domu towarowego. Istnieje wiele kategorii produktów i wiele powodów, dla których ta lista kategorii może się zmienić. Menedżerowie mogą chcieć zaopatrzyć się w nowe linia produktów, pozbyć się innych linii produktów i ewentualnie reorganizować Kategorie od czasu do czasu. Jeśli musisz przebudować i ponownie wdrożyć wszystkie systemy po prostu dlatego, że użytkownicy chcą dodać kategorię produktu, to wziąłeś coś, co powinno być proste i szybkie (dodanie kategorii) i sprawiło, że było to bardzo trudne i powolne.

Podsumowując, liczby są dobre, jeśli dane, które reprezentujesz, są bardzo statyczne w czasie i mają ograniczoną liczbę zależności. Ale jeśli DANE bardzo się zmieniają i ma wiele zależności, wtedy potrzebujesz czegoś dynamicznego, co nie jest sprawdzane w czasie kompilacji (jak tabela bazy danych).

 0
Author: BradB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-01 18:43:05

Użyłbym enums jako użytecznego narzędzia do mapowania, unikając wielokrotności if-else pod warunkiem, że niektóre metody są zaimplementowane.

public enum Mapping {

    ONE("1"),
    TWO("2");

    private String label;

    private Mapping(String label){
        this.label = label;
    }

    public static Mapping by(String label) {

        for(Mapping m: values() {
            if(m.label.equals(label)) return m;
        }

        return null;
    }

}

Tak więc metoda by(String label) pozwala uzyskać wartość wyliczoną przez nie-wyliczoną. Co więcej, można wymyślić mapowanie między dwoma enumami. Można również spróbować "1 do wielu" lub "wiele do wielu" oprócz domyślnej relacji "jeden do jednego"

W końcu, enum jest klasą Javy. Możesz więc mieć w sobie metodę main, która może być przydatna, gdy potrzebujesz wykonać kilka operacje mapowania na args od razu.

 0
Author: TEH EMPRAH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-28 14:24:55