W języku Java Enum może robić wspaniałe rzeczy, które wylicza Enums, ale może również posiadać metody (zachowanie i logikę). Jaka jest przewaga nad używaniem klasy przy użyciu enum? Proste przykłady ilustrujące ten punkt również byłyby mile widziane.Java Enums może mieć zachowanie?
Odpowiedz
Oto prosty przykład:
enum RoundingMode {
UP {
public double round(double d) {
return Math.ceil(d);
}
},
DOWN {
public double round(double d) {
return Math.floor(d);
}
};
public abstract double round(double d);
}
Nie jestem do końca pewien, czy tytuł pytania pasuje do reszty. Tak, Java wylicza zachowania. Mogą też mieć stan, chociaż naprawdę powinien on być niezmienny. (Pomysł na zmienną wartość wyliczenia jest dość przerażającym IMO.)
Wyliczenie w Javie jest w zasadzie ustalonym zbiorem obiektów. Zaletą jest to, że wiesz, że jeśli masz referencję tego typu, to zawsze jest to jeden z dobrze znanych zestawów.
Osobiście uwielbiam wyliczanki Java i życzę, aby C# również je posiadało - są bardziej zorientowane obiektowo niż wyliczenia C#, które są w zasadzie "nazwanymi liczbami". Istnieje kilka "gotch" w zakresie kolejności inicjalizacji, ale są one generalnie super.
nie można naśladować stałe teksty w języku Java z C# klas? –
@Vilx: Oczywiście, że możesz. Przed wprowadzeniem języka Java 5 można było pisać własne klasy, aby tworzyć obiekty enum z typami safe. (Cóż, nadal możesz, oczywiście, nie ma po co.) – Eddie
Vilx: Możesz, ale jest trochę nieprzyjemny. Zasadniczo używasz abstrakcyjnego typu bazowego z prywatnym konstruktorem i wyprowadzasz z niego * typy * zagnieżdżone, które mogą wywoływać prywatny konstruktor. –
W naszym projekcie używamy Enums dla kilku rzeczy, ale być może najważniejszego dla celów i18n - każdy kawałek pokazanego tekstu otrzymuje Enum. Klasa Enum ma metodę zwracającą ciąg, która sprawdza używane ustawienia regionalne i wybiera poprawne tłumaczenie z kolekcji tłumaczeń w środowisku wykonawczym.
Służy to podwójnemu celowi - otrzymujesz kodowanie z IDE, a także nigdy nie zapomnisz przetłumaczyć napisu.
Użycie jest bardzo proste, do tego stopnia, że prawie rendundant dać przykład, ale oto jak można by użyć Translation-enum
System.out.println(Translations.GREET_PERSON.trans()+" "+user.getName());
Albo, jeśli chcesz być wyobraźnia, mają enum przyjąć argumenty, które z jakiegoś magicznego ciąg manipulacji, które są wkładane w zaznaczonej pozycji w łańcuchu tłumaczenia
System.out.println(Translations.GREET_PERSON.trans(user.getName());
Interesujące użycie, ale wydaje się, że można uzyskać to samo zachowanie z serii metod statycznych w klasie. Przypuszczam, że nie widzę korzyści z używania enum. – Dave
Wyliczenia są znacznie łatwiejsze do dodania w razie potrzeby. Są również świadomi siebie - możesz pobrać ciąg enum sam w ramach trans() - dlatego możesz użyć tego jako słowa kluczowego do dopasowania w swojej tabeli tłumaczeń –
Enum
typy to także świetny sposób na wdrożenie prawdziwych singletonów.
Klasyczne wzory singletonowe w języku Java zazwyczaj dotyczą prywatnych konstruktorów i publicznych metod statycznych, ale nadal są podatne na instancję poprzez odbicie lub (serializację). Ochrona typu enum przeciwko temu.
Mimo, że dostajesz jakąś dziwną metodę "za darmo". (W każdym razie singletony są złe.) –
Nie rozumiem komentarza. –
Interesujący punkt. W jaki sposób enum chroni przed odbiciem i deserializacją? Sądzę, że pytam, co właściwie przeszkadza mi w tworzeniu instancji za pomocą refleksji? Czy kompilator rzuca sprawdzony wyjątek? – Dave
Ponieważ instancje wyliczeniowe są pojedynczymi literami, można ich używać w instrukcjach switch
lub przy użyciu ==
w celu sprawdzenia równości.
Zasadniczo, Java wylicza są klasy (nie wierzę, że istnieje różnica na poziomie bajtode), z dodatkową korzyścią posiadania znanego ustalonego zestawu możliwych wystąpień i możliwość używania ich w instrukcjach przełączania .
Możesz emulować "znany ustalony zestaw możliwych instancji" za pomocą zwykłych klas (wzór "enumeratywnie bezpieczny" opisany w niezliczonych książkach i artykułach), ale jest to dość pracochłonne (powtarzane dla każdej takiej klasy), aby uzyskać go działa naprawdę poprawnie w odniesieniu do Serializacji, equals() i hashCode(), i być może kilka innych rzeczy, o których zapomniałem. Wyróżnienia na poziomie języka oszczędzają ci tę pracę. I, jak wspomniano powyżej, w instrukcjach przełączników można używać wyłącznie wyrażeń na poziomie języka.
Są to klasy, ale istnieje różnica na poziomie bajtodu. Po pierwsze, klasy wyliczeniowe mają flagę ACC_ENUM. Zobacz http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf. –
Przyjrzyj się klasom czasowym java/joda, w których można znaleźć mnóstwo pracy.
Oto przykład java.time.Month:
public enum Month implements TemporalAccessor, TemporalAdjuster {
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER;
private static final Month[] ENUMS = Month.values();
public static Month of(int month) {
if (month < 1 || month > 12) {
throw new DateTimeException("Invalid value for MonthOfYear: " + month);
}
return ENUMS[month - 1];
}
// About a dozen of other useful methods go here
}
- 1. Java: Ogólna metoda dla Enums
- 2. Metody w Enums
- 3. Czy Dapper obsługuje Enums?
- 4. Przestrzenie w C# Enums
- 5. Hermetyzacja zdarzeń z Enums
- 6. Enums in Processing 2.0
- 7. Enums, Singleton i Deserialization
- 8. Generowanie JavaScript reprezentacji Enums
- 9. C++ typedefs i enums
- 10. Użycie zagnieżdżonych enums odpowiednich w tym przypadku?
- 11. Niepożądane zachowanie ArrayList usunąć() Java
- 12. Czy operator funkcji może mieć aliasy?
- 13. Czy klasa może nie mieć konstruktora?
- 14. Czy element HTML może mieć dowolne atrybuty?
- 15. Dlaczego FacesServlet nie może mieć wzorca url/*.?
- 16. SlidingDrawer nie może mieć nieokreślonych wymiary
- 17. Ile maksymalnych połączeń może mieć wyrocznia?
- 18. Czy działanie może mieć dwa narzędzia?
- 19. Ile metod może mieć klasa C#?
- 20. Czy zadanie może mieć wiele osób oczekujących?
- 21. Czy delegat może mieć parametr opcjonalny?
- 22. Czy widżet domowy może mieć kontekst?
- 23. Czy NetBeans 7.4 może mieć JDK 1.6 jako domyślną platformę?
- 24. Jak umieścić docrunings na Enums?
- 25. C# enums jako parametry funkcji?
- 26. Czy w java można mieć niepodpisany ByteBuffer?
- 27. mylące przypadek zachowanie z java static int
- 28. niemożliwe zachowanie wywołania metody języka Java
- 29. Dziwne zachowanie Java zerowy w Metodzie Przeciążenie
- 30. Czy to normalne zachowanie w regex Java?
W jaki sposób użyłbyś tego w kodzie? Czy po prostu to robię? double foo = RoundingMode.round (20.3); A może rozszerzyłbyś wyliczenie na enum dziecka? Jestem odrzucony przez abstrakcyjną metodę. – Dave
Metoda abstrakcyjna jest nadpisywana przez zagnieżdżone klasy używane przez UP i DOWN. Używałbyś go w kodzie jak poniżej: double doMath (RoundMode m, double x, double y) {double d; ... d = m.round (d); ... return d; } Jako pierwszy parametr przekazujesz RoundingMode.UP lub RoundingMode.DOWN. –
Dzięki! Nie jestem pewien jak się z tym czuję, ale rozumiem to teraz;) – Dave