Kilka razy widziałem, jak ludzie używają tytułowych lub nawet małych liter dla stałych enum, na przykład:
enum Color {
red,
yellow,
green;
}
Dzięki temu praca z ich ciągiem znaków jest prosta i łatwa throw new IllegalStateException("Light should not be " + color + ".")
, na przykład , jeśli chcesz .
Wydaje się to bardziej akceptowalne, jeśli wyliczenie jest private
, ale nadal mi się nie podoba. Wiem, że mogę utworzyć konstruktor enum z polem String, a następnie zastąpić toString, aby zwrócić tę nazwę, tak jak poniżej:
enum Color {
RED("red"),
YELLOW("yellow"),
GREEN("green");
private final String name;
private Color(String name) {
this.name = name
}
@Override public String toString() {
return name;
}
}
Ale spójrz, jak długo to trwa. To irytujące, jeśli masz mnóstwo małych wyliczeń, które chcesz uprościć. Czy można tutaj używać niekonwencjonalnych formatów spraw?
java
conventions
enum
łamacz kodów
źródło
źródło
Light should not be RED.
. W końcu ta wiadomość jest dla programisty, użytkownik nigdy nie powinien jej zobaczyć.Light should not be YELLOW.
, zgaduję, że jest to jakaś stała, metoda toString () służy tylko do debugowania, więc nie rozumiem, dlaczego musisz zmienić wygląd tego komunikatu.Odpowiedzi:
Krótka odpowiedź brzmi oczywiście, czy chcesz zerwać z konwencjami nazewnictwa dla zasadniczo stałych ... Cytując z JLS :
Długa odpowiedź, jeśli chodzi o użycie
toString()
, to zdecydowanie metoda zastępowania, jeśli chcesz bardziej czytelnej reprezentacjienum
wartości. Cytowanie zObject.toString()
(moje podkreślenie):Teraz nie jestem pewien, dlaczego niektóre odpowiedzi skłaniały do mówienia o konwersji
enums
naString
wartości z powrotem na wartości, ale ja też tutaj przedstawię swoje zdanie. Taką serializacjęenum
wartości można łatwo rozwiązać za pomocą metodname()
lubordinal()
. Oba sąfinal
i dlatego możesz być pewien zwracanych wartości , o ile nazwy lub położenie wartości nie ulegną zmianie . Dla mnie to wystarczająco wyraźny marker.To, co zbieram z powyższego, brzmi: dzisiaj możesz chcieć opisać
YELLOW
jako po prostu „żółty”. Jutro możesz opisać to jako „Pantone Minion Yellow” . Opisy te powinny być zwrócone z wywołaniemtoString()
, a ja nie spodziewałbym alboname()
lubordinal()
zmienić. Jeśli to zrobię, muszę to rozwiązać w ramach mojej bazy kodu lub mojego zespołu i staje się większym pytaniem niż tylkoenum
stylem nazewnictwa .Podsumowując, jeśli wszystko, co zamierzasz zrobić, to zapisać bardziej czytelną reprezentację swoich
enum
wartości, nadal sugeruję trzymanie się konwencji, a następnie zastępowanietoString()
. Jeśli zamierzasz również serializować je do pliku danych lub do innych miejsc docelowych innych niż Java, nadal masz metodyname()
iordinal()
, aby utworzyć kopię zapasową, więc nie musisz się martwić o zastąpienietoString()
.źródło
Nie modyfikuj
ENUM
, to po prostu nieprzyjemny zapach kodu. Niech wyliczenie będzie wyliczeniem, a łańcuch ciągiem.Zamiast tego użyj wartości konwertera CamelCase.
Istnieje wiele bibliotek typu open source, które już rozwiązują ten problem dla Java.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/CaseFormat.html
źródło
Wysyłając wyliczenia między moim kodem Java a bazą danych lub aplikacją klienta, często kończę na czytaniu i zapisywaniu wartości wyliczania jako ciągów.
toString()
nazywa się niejawnie podczas łączenia łańcuchów. Przesłonięcie metody toString () w niektórych wyliczeniach oznaczało, że czasami mogłem po prostui czasami musiałem pamiętać, żeby zadzwonić
co doprowadziło do błędów, więc już tego nie robię. Właściwie nie zastępuję żadnych metod na Enum, ponieważ jeśli podrzucisz je do wystarczającej liczby kodów klienta, ostatecznie złamiesz czyjeś oczekiwania.
Zrobić własną nową nazwę metody, jak
public String text()
itoEnglish()
czy cokolwiek innego.Oto mała funkcja pomocnika, która może zaoszczędzić trochę pisania, jeśli masz wiele wyliczeń takich jak powyżej:
Zawsze łatwo jest wywołać .toUpperCase () lub .toLowerCase (), ale odzyskanie mieszanych liter może być trudne. Rozważ kolor „bleu de France”. Francja jest zawsze pisana wielkimi literami, więc jeśli chcesz, możesz dodać metodę textLower () do swojego wyliczenia. Kiedy użyjesz tego tekstu na początku zdania, w środku zdania, a w tytule, zobaczysz, jak jedna
toString()
metoda może się nie udać. I to nawet nie dotyka znaków, które są niedozwolone w identyfikatorach Java, lub których pisanie jest trudne, ponieważ nie są reprezentowane na standardowych klawiaturach, ani znaków, które nie mają wielkości liter (Kanji itp.).Prawidłowe korzystanie z nich nie jest takie trudne:
Mam nadzieję, że to również pokazuje, dlaczego stosowanie wartości wyliczania mieszanych wielkości liter również Cię rozczaruje. Ostatnim powodem, dla którego warto trzymać się wielkich liter ze stałymi enum podkreślenia, jest to, że postępuje to zgodnie z zasadą najmniejszego zdziwienia. Ludzie tego oczekują, więc jeśli zrobisz coś innego, zawsze będziesz musiał wyjaśniać siebie lub radzić sobie z ludźmi niewłaściwie używającymi twojego kodu.
źródło
toString()
wyliczenia, nie ma dla mnie sensu. Jeśli chcesz zagwarantować domyślne zachowanie nazw wyliczeń, użyjname()
. Nie wydaje mi się, by „kusiło”, aby polegać natoString()
zapewnieniu właściwego kluczavalueOf(String)
. Sądzę, że jeśli chcesz dowodzić idiotyzmem swoich wyliczeń, to jedno, ale nie sądzę, żeby to był wystarczający powód, aby zalecać, abyś nigdy nie zastępowałtoString()
.<input type='checkbox' value=" + MY_CONST1 + ">
, a czasem musiałem pamiętać o wywołaniu<input type='checkbox' value=" + MY_CONST1.name() + ">
, co prowadziło do błędów.Jeśli istnieje najmniejsza szansa, że te reprezentacje ciągów mogą być przechowywane w miejscach takich jak bazy danych lub pliki tekstowe, to powiązanie ich z rzeczywistymi stałymi wyliczania stanie się bardzo problematyczne, jeśli kiedykolwiek będziesz musiał zmienić swoje wyliczenie.
Co jeśli kiedyś zdecydujesz się zmienić nazwę
Color.White
, abyColor.TitaniumWhite
podczas gdy istnieją dane pliki tam zawierające „białe”?Ponadto, gdy zaczniesz konwertować stałe wyliczeniowe na ciągi, następnym krokiem w dalszej części będzie wygenerowanie ciągów, które użytkownik będzie mógł zobaczyć, a problemem jest, jak jestem pewien, że już wiesz, że składnia java nie zezwalaj na spacje w obrębie identyfikatorów. (Nigdy nie będziesz miał
Color.Titanium White
.) Tak więc, ponieważ prawdopodobnie będziesz potrzebować odpowiedniego mechanizmu do generowania nazw wyliczeń, aby pokazać je użytkownikowi, najlepiej unikać niepotrzebnego komplikowania wyliczenia.To powiedziawszy, możesz oczywiście iść naprzód i zrobić to, o czym myślisz, a następnie przefakturować swój wyliczenie później, aby przekazać nazwy konstruktorowi, kiedy (i jeśli) napotkasz kłopoty.
Możesz ogolić kilka linii ze swojego enum-z-konstruktorem, deklarując
name
polepublic final
i tracąc gettera. (Jaką miłość mają programiści Java w stosunku do getterów?)źródło
public final static int white = 1;
lubpublic final static String white = "white";
(oprócz ponownego zerwania konwencji), traci to bezpieczeństwo typu, które zapewnia wyliczenie.public final
instancji inicjowane z konstruktora zachowuje się dokładnie tak samo, jak pole nie-końcowe, z tym wyjątkiem, że podczas kompilacji nie można przypisać do niego pola . Możesz go zmodyfikować poprzez odbicie, a cały odnoszący się do niego kod natychmiast zacznie widzieć nową wartość.Prawdopodobnie przestrzeganie konwencji NAZWY DUŻYCH narusza OSUSZANIE . (I YAGNI ). np. w twoim kodzie przykład 2: „RED” i „red” są powtarzane.
Czy przestrzegasz oficjalnej konwencji, czy postępujesz zgodnie z zasadą DRY? Twoja decyzja.
W moim kodzie będę śledzić DRY. Zamieszczę jednak komentarz do klasy Enum, mówiąc: „nie wszystkie wielkie litery, ponieważ (wyjaśnienie tutaj)”
źródło