2017-11-18 5 views
0

In C++ gibt es also einen Präprozessor, der die Präprozessor-Direktiven durch Werte ersetzt. Jetzt ist meine Frage: JAVA Gibt es so etwas wie einen Pre-Prozessor in Java? Jetzt. Wir wissen, dass der Fallwert der switch-Anweisung in Java etwas sein muss, das in der Kompilierungszeit ausgewertet wird. Zum Beispiel:JAVA Gibt es in Java so etwas wie einen Preprozessor?

int month = 5; 
switch(month) { 
    case 1: doSth() break; 
    ... 
    case month: doSth() break; 

Jetzt in diesem Beispiel kann ich nicht verwenden „Fall Monat:“, weil der Wert des Variablen Monats wird in der Laufzeit ausgewertet zu werden. Aber wenn ich letzte Schlüsselwort wie folgt hinzu:

final month = 5; 

Und danach, wenn ich das gleiche tun, sondern mit der Variable, die das Schlüsselwort final alles hat funktioniert. Jetzt könnten Sie mir erklären, was ist das und ist dieser "vorverarbeitete" Code für mich zugänglich?

+4

* 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. –

+0

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. –

+0

@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

Antwort

0

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.

Verwandte Themen