Więc pracuję nad tą klasą, która ma kilka stałych statycznych:
public abstract class Foo {
...
public static final int BAR;
public static final int BAZ;
public static final int BAM;
...
}
Następnie chciałbym znaleźć sposób na uzyskanie odpowiedniego ciągu znaków na podstawie stałej:
public static String lookup(int constant) {
switch (constant) {
case Foo.BAR: return "bar";
case Foo.BAZ: return "baz";
case Foo.BAM: return "bam";
default: return "unknown";
}
}
Jednak podczas kompilacji pojawia się constant expression required
błąd na każdej z 3 etykiet przypadków.
Rozumiem, że kompilator potrzebuje wyrażenia, które ma być znane w czasie kompilacji, aby skompilować przełącznik, ale dlaczego nie jest Foo.BA_
stała?
java
compile-time-constant
Austin Hyde
źródło
źródło
public static final int
są rozproszone po całym JDK, więc z tym poszedłem.Odpowiedzi:
Chociaż są one stałe z punktu widzenia dowolnego kodu wykonywanego po zainicjowaniu pól, nie są one stałymi czasowymi kompilacji w sensie wymaganym przez JLS; zobacz §15.28 Wyrażenia stałe, aby poznać specyfikację wyrażenia stałego 1 . Odnosi się to do §4.12.4 Zmienne końcowe, które definiują „stałą zmienną” w następujący sposób:
W naszym przykładzie zmienne Foo.BA * nie mają inicjatorów i dlatego nie kwalifikują się jako „zmienne stałe”. Poprawka jest prosta; zmień deklaracje zmiennych Foo.BA *, aby miały inicjatory, które są wyrażeniami stałymi czasu kompilacji.
W innych przykładach (gdzie inicjatory są już wyrażeniami stałymi czasu kompilacji), deklarowanie zmiennej jako
final
potrzebnej.Możesz zmienić kod tak, aby używał
enum
zamiastint
stałych, ale wiąże się to z kilkoma innymi ograniczeniami:default
sprawy, nawet jeślicase
dla każdej znanej wartości instrumentuenum
; zobacz Dlaczego w przypadku przełączania wyliczenia jest wymagana wartość domyślna?case
etykiety muszą być jawnymienum
wartościami, a nie wyrażeniami, których wynikiem jestenum
wartości.1 - Ograniczenia stałych wyrażeń można podsumować w następujący sposób. Wyrażenia stałe a) mogą używać typów pierwotnych i
String
tylko, b) zezwalać na operacje podstawowe, które są literałami (oprócznull
) i tylko zmiennymi stałymi, c) zezwalać na wyrażenia stałe, które mogą być ujęte w nawiasy jako podwyrażenia, d) zezwalać na operatory z wyjątkiem operatorów przypisania++
,--
lubinstanceof
, i e) zezwalaj na rzutowanie typów na typy pierwotne lubString
tylko.Należy pamiętać, że to nie obejmuje żadnej formy lambda lub metody połączeń
new
,.class
..length
lub indeksowanie tablicy. Ponadto wszelkie użycie wartości tablicowych,enum
wartości, wartości pierwotnych typów opakowań, pudełek i rozpakowywania są wykluczone ze względu na a).źródło
Otrzymujesz Wymagane wyrażenie Stałe, ponieważ pozostawiłeś wartości bez stałych. Próbować:
źródło
Mam ten błąd na Androidzie, a moim rozwiązaniem było użycie:
zamiast
źródło
Ponieważ nie są to stałe czasu kompilacji. Rozważ następujący prawidłowy kod:
Możesz poznać wartość tylko
BAR
w czasie wykonywania.źródło
public static final int BAR = new Random().nextInt()
?new Random().nextInt()
zwrócić tych samych wartości?Możesz użyć wyliczenia, takiego jak w tym przykładzie:
Źródło: instrukcja Switch z wyliczeniem
źródło
enum Codes { CODE_A(1), CODE_B(2); private mCode; Codes(int i) { mCode = i; } public int code() { return mCode; } }
<br/> Kiedy próbuję użyć wyliczenia w przełączniku, pojawia się ten sam błąd ... <br/>switch(field) { case Codes.CODE_A.code() : // do stuffs.. ; }
<br/> Czy można rozwiązać problem?Odpowiedziano na to wieki temu i prawdopodobnie nie ma to znaczenia, ale na wszelki wypadek. Kiedy stanąłem przed tym problemem,
if
zamiast tego użyłem po prostu oświadczeniaswitch
, rozwiązało to błąd. Jest to oczywiście obejście i prawdopodobnie nie jest to „właściwe” rozwiązanie, ale w moim przypadku wystarczyło.źródło
switch
jest to generalnie szybsze niż długieif-else
, ponieważswitch
sprawdź stan tylko raz , podczas gdy w przypadkuif-else
może być konieczne sprawdzenie wszystkich warunków, zanim znajdziesz właściwy.Czasami zmienna switch może również powodować ten błąd, na przykład:
Aby rozwiązać, należy rzutować zmienną na int (w tym przypadku). Więc:
źródło
Mam ten błąd w Androidzie, robiąc coś takiego:
pomimo deklarowania stałej:
public static final String ADMIN_CONSTANT= "Admin";
Rozwiązałem problem, zmieniając kod na ten:
źródło
W moim przypadku otrzymałem ten wyjątek, ponieważ
w drugim przypadku wywołałem stałą z instancji,
var.MODIFICAR_KM:
ale powinienem użyćVariablesKmDialog.OBTENER_KM
bezpośrednio z klasy.źródło
Jeśli używasz go w przypadku przełącznika, musisz pobrać typ wyliczenia, nawet przed podłączeniem tej wartości do przełącznika. Na przykład :
A wyliczenie jest takie:
źródło
Poniższy kod jest oczywisty, możemy użyć wyliczenia z obudową przełącznika:
Na podstawie wartości klas z wyliczenia można zmapować:
Mam nadzieję, że to pomoże :)
źródło
Polecam skorzystać z następującego sposobu:
źródło
private Animal(String name) { this.name = name; }
Polecam używanie wyliczeń :)
Sprawdź to:
Następnie możesz go użyć w ten sposób:
źródło