Also nach der Kompilierzeit im Bytecode gibt es keine Variable "Monat" im Speicher und "5" steht an den Stellen wo "Monat" war?
Ja und nein. Was passiert, ist das Schlüsselwort final
sagt dem Compiler die Variable kann sich nie ändern, so kann es als eine Konstante behandelt und an Orten verwendet werden, wo eine Konstante erforderlich ist. Wie dies unter den Deckungen geschieht, ist unerheblich, aber in der Praxis wird der konstante Wert ersetzt.
Lassen Sie uns jetzt Ihren Code betrachten:
int month = 5;
switch(month) {
case 1: doSth() break;
...
case month: doSth() break; // compilation error
Es gibt etwas hier nicht richtig, da Ihr Switch Variable die gleiche wie einer Ihrer Fälle ist. Der einzig mögliche Weg ist der month
Fall, also sind alle anderen Fälle toter Code. Vielleicht meinte Sie:
int monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Still a compilation error
Dies ist ein wenig besser aussieht, aber da monthOfInterest
kompilieren nicht ist kein „konstanter Ausdruck“. Hier kommen wir zu Ihrer ursprünglichen Frage. Fallselektoren müssen entweder numerische Literale oder Ausdrücke sein, die zur Kompilierungszeit ausgewertet werden können. So ändern wir dies:
final int monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // This is valid code
Dieses „verhält sich“ als ob monthOfInterest
durch die ständige 5
ersetzt wurde. Beachten Sie, dass dies nicht das Gleiche wie:
final int monthOfInterest;
...
monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Oops, compilation error again
Es vollkommen legal ist später eine Variable final
und initialisieren es zu erklären. Der Compiler stellt sicher, dass Sie den Wert nur einmal festlegen, aber in diesem Fall ist monthOfInterest
kein konstanter Ausdruck mehr, und dieser Code wird nicht kompiliert.
Eine letzte Anmerkung. in Betracht ziehen:
final int monthOfInterest = 1;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Oops again, different compilation problem
Dies kann nicht kompiliert werden, da Sie jetzt zwei Fälle mit dem gleichen Wert haben.
* JAVA Gibt es in Java so etwas wie einen Präprozessor? * ** Nein. ** Es gibt keinen Java-Präprozessor. Das Schlüsselwort final macht die Variable zu einer Konstante. –
oft Fälle wie oben können mit 'enums' modelliert werden. Oder, wenn Sie wirklich eine dynamische case/switch-Anweisung benötigen, verwenden Sie eine Musterbibliothek oder eine Lambda-Version einer switch-Anweisung. –
@Eliott Frisch Also nach der Kompilierzeit im Bytecode gibt es keine Variable "Monat" im Speicher und "5" steht an den Stellen wo "Monat" war? – BoSsYyY