2012-10-22 13 views
8

Nie wiem, czy tylko ja to wiem, ale wartości wyliczenia nie są domyślnie ostateczne i można je modyfikować.Java wymyśla zastosowania i możliwości zmienności?

enum EnumTest { 
    TOTO("TOTO 1"), 
    TATA("TATA 2"), 
    ; 

    private String str; 

    private EnumTest(String str) { 
     this.str = str; 
    } 

    @Override 
    public String toString() { 
     return str; 
    } 
    } 

    public static void main(String[] args) { 
    System.out.println(EnumTest.TATA); 
    EnumTest.TATA.str = "newVal"; 
    System.out.println(EnumTest.TATA); 
    } 

TATA 2 
newVal 

Wartości te są oftenly zainicjowana podczas tworzenia instancji (TOTO("TOTO 1")), ale oprócz mnie, nigdy nie widziałem nikogo, używając końcowego słowa kluczowego enum dla zmiennych, które powinny być niezmienne. Nie o to chodzi, tylko zastanawiam się, czy jestem tego jedyny świadomy.

Co chciałbym wiedzieć, czy był jakiś przypadek, aby utworzyć zmienne wyliczenia?

Chciałbym również poznać granice tego, co możemy zrobić z wyliczeniem (dobra praktyka lub nie). Nie testowałem tego, ale może enum może zostać wstrzyknięty fasolą Spring? Przynajmniej wydaje się, że możemy opisać każdą instancję (@Deprecated działa dobrze na przykład), a także metody.

+7

Używanie 'final' dla pól jest powszechną praktyką w wyliczeniach. –

Odpowiedz

7

Jednym z możliwych przykładów użycia byłoby leniwy inicjowanie (obliczyć niektóre wartości pól, gdy są po raz pierwszy używane, jeśli często nie są w ogóle używane) lub "normalny", zmienny obiekt singletowy (jak rejestr lub inny).

W większości przypadków obiekty enum powinny być niezmienne, a ich pola muszą być ostateczne.

-3

Co chciałbym wiedzieć, czy był jakiś przypadek, aby utworzyć zmienne wyliczenia?

Stałe enum nie są same w sobie zmienne, ich pola są zmienne.

+1

To właśnie ma na myśli, tak jak ja to rozumiałem. –

+0

Tak właśnie mam na myśli, ale "ogólnym" przypadkiem jest tworzenie niezmiennych wyliczeń, ale nikt nie używa "końcowego". –

+0

Dzieje się tak, ponieważ rzadko zdarza się "wyliczenie" z "publicznym" polem lub publiczną metodą zmiany pola IMHO . Zgadzam się jednak, że pola powinny być zadeklarowane jako "ostateczne". –

6

Podczas wskazania interesującego faktu tutaj, o ile mi wiadomo, nie ma tu zastosowania dla zmiennych pól wyłudzeniowych. Istnieje wiele powodów, dla których wykorzystanie "funkcji" tego języka ("błędu"?) Byłoby złym pomysłem, a jednym z nich jest możliwość pomylenia innych programistów.

+3

Zgadzam się, że wyliczenia są ogólnie uważane za niezmienne, a tym samym tworzenie mutowalnych wyrażeń może prowadzić do niewłaściwego użycia. Sugerowałbym, że wartości zmienne związane z wyliczeniami najlepiej byłoby pomóc w "EnumMap". To powiedziawszy, myślę, że powiedzenie "nie ma sensu" jest zbyt silne. Wyliczenia w praktyce reprezentują przedłużenie wzoru singlton (ustalona liczba wystąpień) i mając to na uwadze można zastosować jak każdą inną klasę. Ponownie powtarzam, że większość programistów używających MOST uważa je za IMMUTABILNE, a zatem zmienne wyliczenia mogą prowadzić do problemów związanych z konserwacją. –

+0

Dzięki Bogu, ponieważ są przyjmowane jako immutabl, nie ma generalnie żadnego setera :) –

+0

@JohnB, jeśli możesz wymyślić dobry przykład sytuacji, w której używanie enum z zmiennymi polami jest prawdopodobnie lepsze niż jakakolwiek alternatywa, byłbym wdzięczny widząc to jako osobna odpowiedź. Ale moja odpowiedź brzmi: jeśli chodzi o mnie, nie ma ** przypadkiem użycia, a przynajmniej nie jest to przypadek, który nie mógłby być lepiej obsłużony zwykłą "klasą". Masz rację co do wyliczenia "w praktyce", ale koncepcyjnie są one bliższe 'boolean' (które ma ustalony zestaw 2 możliwych wartości) lub' int' (ustalony zestaw 2^32-1 możliwych wartości) . Czy potrafisz sobie wyobrazić, że posiadasz zmienne pola na 'true'? –

3

W odpowiedzi na odpowiedź i komentarz Alexa, przyjmuję jego sugestię o zamieszczeniu możliwego przypadku użycia. Weźmy stary standardowy przykładowy planeta, z której można obliczyć grawitację. Wyobraź sobie, że chcesz utrzymać liczbę ludzkich kolonii na każdej planecie. Tak, możesz użyć EnumMap, ale mógłbym zobaczyć przypadek, w którym może być potrzebnych coraz więcej zmiennych pól, a posiadanie osobnej mapy dla każdej wartości lub osobnej klasy, która utrzymywałaby zmienne wartości związane z wyliczeniem, byłoby sprzeczne z intuicją.

Jak już stwierdziłem w moich komentarzach, ogólnie sądzę, że wyliczenia zwykle są i powinny być niezmienne, ale uważam, że stwierdzenie, że nie ma przypadków użycia, jest zbyt silne.

1

Nie widzę powodu, aby zabronić używania zmiennych pól w enum s. Jeden używa enum do stwierdzenia, że ​​wartość typu należy do jednego ze skończonych (i znanych) zestawów możliwości. Nie oznacza to, że wartości te nie mogą mieć właściwości, które ewoluują w czasie.

Niektórzy pytali o przypadki użycia takiego scenariusza. Jednym z przykładów może być użycie typu enum, takiego jak ErrorCategory, który klasyfikowałby błąd do jednej z wielu predefiniowanych kategorii (np .: DocumentationError, SemanticError, LayoutError ...).

Załóżmy, że te ErrorCategories mają właściwości, takie jak requiresInstantIntervention lub shouldFailBuild. Mogę sobie wyobrazić, że wartość tych właściwości może zmieniać się w czasie lub że mogą być konfigurowane przez użytkownika.

Zdaję sobie sprawę, że istnieje (wiele) innych sposobów na jego wdrożenie (takich jak wspomniana wyżej EnumMaps) i zawsze można się spierać o styl, ale dla mnie takie użycie enum s nie jest samo w sobie złe. Ponieważ enum s są typami referencyjnymi w java, zachowanie == pozostaje takie samo, jak gdyby nie było żadnych właściwości zmiennych.

0

Instancja wyliczeniowa jest publicznym statycznym końcowym polem klasy wyliczeniowej. Więc jeśli jest zmienna, możesz zmienić jej stan w innym wątku. Może nie być to, co chcesz i może powodować problemy, jeśli nie zdajesz sobie z tego sprawy.

Powiązane problemy