2011-12-05 21 views
18

Im pracy na java, Stworzyłem enum następująco:Java enum elements with spaces?

public enum myEnum 
{ 
    india, 
    russian, 
    england, 
    north America 
} 

Powyższy przykład daje błędy podczas korzystania z miejsca w nazwie elementu (tj Ameryka Północna). Jakieś sugestie, jak rozwiązać powyższy problem?

+1

Dostęp do tego członka również nie byłby możliwy; pomyśl o 'myEnum x = myEnum.north America'. Nie będzie to możliwe, ponieważ jeśli pozwolisz na takie nazwy, gdzie ustawić koniec identyfikatora? Może powinna być dołączona następna linia kodu lub oświadczenie? – Matten

+1

NIE używaj małych liter do wyliczania, a nawet do nazwy klasy! – banterCZ

Odpowiedz

52

Nie można umieścić spacji w środku identyfikatora.

Powoduje to, że ten identyfikator i parser zakładają, że wszystko, co nadejdzie, jest ważnym tokenem w kontekście tej instrukcji. Jest kilka (jeśli w ogóle) miejsc, które byłyby legalne.

nazwy wartość Konwencjonalna Java byłoby:

INDIA,   // Or India, 
RUSSIA,  //  Russia, 
NORTH_AMERICA; //  NorthAmerica; 

enum może mieć właściwości towarzyszące, takie jak człowieka czytelnych nazw np

public enum CountryAndOneContinent { 

    INDIA("India"), 
    RUSSIA("Russia"), 
    NORTH_AMERICA("North America"); 

    private String displayName; 

    CountryAndOneContinent(String displayName) { 
     this.displayName = displayName; 
    } 

    public String displayName() { return displayName; } 

    // Optionally and/or additionally, toString. 
    @Override public String toString() { return displayName; } 
} 

jestem ambiwalentny temat korzystania toString dostarczać reprezentacji warstwy prezentacji.

Wolę metody, które wyraźnie wyrażają swój cel. – jest bardziej wyrazisty i oczywisty.

toString jest dość ogólna i umożliwia tylko pojedynczą reprezentację. W zależności od kontekstu, parametrów itp. Może być wymaganych wiele formatów wyjściowych, na które nie zezwala toString.

Zalety toString obejmują użycie domyślnych operacji na łańcuchach na obiekcie, aw tym przypadku użycie valueOf do bezpośredniej translacji z wersji czytelnej dla człowieka do wartości wyliczeniowej.

+2

Możesz potrzebować innej nazwy niż nazwa ... (Tylko jeden element w OP jest kraj rzeczywisty, kraj, język, kraj będący jego składnikiem i kontynent.Zupełnie wyliczenie.) –

+2

+1 za wspomnienie o problemie z 'toString()'. Możesz użyć metody 'getDisplayName()' zamiast używać 'toString()'. – Jesper

+0

@Jesper Tak, przypuszczam, że dla rzeczy, które wyglądają specjalnie dla 'getXxx' - zostawiłem to un-JavaBeany. –

3

Zapisz je razem jako northAmerica lub użyj podkreślenia north_America.

+0

Dziękuję Tudor, ale nie chcę robić jak powyżej, jak powiedziałeś. trzeba zachować te słowa oddzielone. – BSalunke

+3

@Balunke Nie możesz. Można jednak utworzyć "wyliczenie" z wartością. Zobacz aktualizację. –

+2

Wystarczy podkreślić to, co mówi Dave Newton: Nie możesz, po prostu nie działa w ten sposób. – Tudor

1
public enum myEnum 
{ 
    india, 
    russian, 
    england, 
    north_america 
} 

Aby wartościami dostępu

myEnum.values() 
+0

NIE używaj małych liter do wyliczania, a nawet do nazwy klasy! – banterCZ

+0

@banterCZ sic erat scriptum –

2

Java naming rule nie pozwala spacji jako możliwych znaków w nazwach zmiennych, klas, teksty stałe i członków enum (i każdego innego identyfikatora). Dlatego ten "problem" nie może zostać rozwiązany. Po prostu użyj `north_america 'jako nazwy członka!

An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.

The Java letters include uppercase and lowercase ASCII Latin letters A-Z (\u0041-\u005a), and a-z (\u0061-\u007a), and, for historical reasons, the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $ character should be used only in mechanically generated source code or, rarely, to access preexisting names on legacy systems.

The "Java digits" include the ASCII digits 0-9 (\u0030-\u0039).

+0

To błąd składni, możesz napisać kod kompilowany bez przestrzegania konwencji. –

+0

Nie jestem native speakerem angielskiego, ale dla mnie zrozumienie powinno być nazywane konwencją :-) – Matten

+0

'public enum myEnum' tutaj nie jest zgodne z konwencją. Ale "Północna Ameryka" jest błędem składni i nie będzie się kompilować. –

4

Problem nie ma nic wspólnego (konkretnie) z wyliczeniami: w Javie nazwy nie mogą zawierać spacji. Spróbuj wyeliminować spację (używając wielkich liter, aby odróżnić bity) lub zamiast nich użyj podkreśleń.

14

Jestem gong iść do przodu i zgadnij, dlaczego chcesz miejsce w nazwie; ponieważ chcesz odwoływać się do tego jako ciąg znaków.

Więc to zrobić:

public enum MyEnum { 
    INDIA("India"), 
    RUSSIAN("Russian"), 
    ENGLAND("England"), 
    NORTH_AMERICA("North America");  

    private String name; 

    MyEnum(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return this.name; 
    }  
} 

Można rozważyć nadrzędny ciąg.

public toString() { 
    return name; 
} 

Zaletą nadrzędnym toString() jest to, że ten ciąg może być również stosowany w MyEnum .valueOf (myString). Nadpisywanie toString w zasadzie tworzy HashMap wartości wyliczeniowych.

+2

Jeśli coś nie mam, ten przykład nie działa w Javie 8; 'MyEnum.valueOf (" North America ")' i 'MyEnum.valueOf (MyEnum.NORTH_AMERICA.toString())' obaj wyrzucają ten sam błąd: 'IllegalArgumentException Brak stałej enum ofi.devops.cmwf.model.trigger.MyEnum.North America' – raffian

1

po prostu stwórz własną funkcję valueOf like w klasie wyliczeniowej. Zamień spacje na podkreślenia. nazwij swoje stałe wyliczeniowe, takie jak ta "north_america (" North America ")". Jeśli metoda nie znajdzie Twojego wyliczenia, po prostu zwraca parametr.

public static String valueOfOrDefault(String myValue) { 
//replace space with underscore so it matches enum name 
     String value=myValue.toUpperCase().replaceAll("\\s", "_"); 
     for(myEnum type : myEnum.class.getEnumConstants()) { 
      if(type.name().equalsIgnoreCase(value)) { 
      return type.toString(); 
      } 
     } 
     return myValue; 
     } 
0

Wprowadziłem również własną metodę valueOf. Ale wracam z typem Enum i nie muszę konwertować "checkString" na przykład, checkString to "Petty Cash".

JournalType journalType = JournalType.valueOfOrDefault (checkString);

public enum JournalType { 

MISC_BILLING("Misc Billing"), 
MISC_BILLING_AUTONUM("Misc Billing AutoNum"), 
PRETTY_CASH("Petty Cash"), 
RECURRING_AP("Recurring AP"), 
GL_JOURNAL("GL Journal"), 
GDS_NDS("GDS/NDS"); 

private final String journalType; 

JournalType(String journalType) { 
    this.journalType = journalType; 
} 

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

public static JournalType valueOfOrDefault(String myValue) { 
    for(JournalType type : JournalType.class.getEnumConstants()) { 
     if(type.toString().equals(myValue)) { 
      return type; 
     } 
    } 
    throw new IllegalArgumentException("JournalType not found"); 
} 

}