2014-03-29 4 views
8

Entschuldigung für meine Ignoranz. Ich konnte den Unterschied zwischen den folgenden scheinbar ähnlichen Codezeilen nicht verstehen. Was ist der Unterschied zwischen den beiden folgenden Zeilen des Java-Codes?

  1. final int num1 = 1;
  2. final int num2;num2 = 2;

Was macht die num2 keinen Anspruch auf einen Schalter Fall konstant?

switch (expression) { 
     case num1: 
      System.out.println("Case A"); 
     case num2: 
      System.out.println("Case B"); 
    } 
+1

Können Sie uns zeigen, wie Sie das verwenden, dass Sie einen Fehler erhalten? Solange Sie num2 vor dem Einschalten deklarieren und initialisieren, sollte es kein Problem geben. – user1205577

+1

Die Antworten hier und die Diskussion in den Kommentaren können helfen: http://stackoverflow.com/questions/16255270/final-variable-case-in-switch-statement Auch als Duplikat markieren. –

+0

Ja, [diese] (http://stackoverflow.com/a/16255341/2358786) ist die Antwort. num1 ist die Kompilierzeitkonstante, während num2 nicht ist. – kiruwka

Antwort

7

Zum Java Language Specification wir gehen. Eine switch Erklärung des case Etiketten werden als

definiert
SwitchLabel: 
    case ConstantExpression : 
    case EnumConstantName : 
    default : 

Ihre num Variable bezieht sich nicht auf eine enum konstanten Namen, so lassen wir das ignorieren. Was ist ein ConstantExpressions? Die JLS definiert erneut

Kompilierungszeit-konstanter Ausdruck ist ein Ausdruck einen Wert primitiven Typs oder ein String bezeichnet, die nicht abrupt nicht komplett und ist nur wie folgt zusammen verwendet:

  • Literale primitiver Art und Literale vom Typ String
  • [...]
  • Einfache Namen (§6.5.6.1), die auf konstante Variablen (§4 beziehen. 12.4).

So ist die primitive int Wert 2 ist ein konstanter Ausdruck. Sie tun können,

switch { 
    case 2: 
} 

Jetzt wollen wir die Beziehung mit der Verwendung von final und konstanter Größe kennen.

A blankfinal ist eine Variable, deren Erklärung final fehlt einen Initialisierer. [...]

Eine Variable des primitiven Typs oder Typs String, dh final und mit einem Kompilierzeit-konstanten Ausdruck initialisiert (§15.28), ist ein konstanten Variable genannt.

Damit letzte Zitat bezieht sich auf eine nicht leerefinal variabel, dh. eine, die einen Initialisierer hat.

So

final int num1 = 1; 

ist eine konstante Größe.

Und

final int num2; 
num2 = 2; 

ist nicht und kann daher nicht in einem case Etikett verwendet werden.

-2

in num1 Sie es sofort zu initialisieren, in num2 Sie sofort nicht ordnen Sie sie es den Wert später auf

+0

Es ist klar wie Tageslicht. Aber was ist der Punkt in num2, der im switch case nicht als Konstante in Frage kommt? –

+0

@Phoenix ist, weil die Compiler und Switch-Anweisungen typenabhängig sind, und indem Sie es abschließen, stellen Sie sicher, dass es Wert oder Typ nicht ändern kann. Wie wenn Sie es auf einer jcombobox verwenden, müssen Sie das Feld als endgültig festlegen, bevor Sie eine switch-Anweisung ausführen können –

+2

Ich kaufe diese Erklärung nicht ... Frage ist gut, diese Erklärung fehlt Verweis (auf die JLS, wahrscheinlich) – fge

0

Also, Ihre Frage zu beantworten: num1 ist kompilieren-Zeitkonstante, so Compiler kann es im Wesentlichen ersetzen mit 1:

switch(whatever) { 
    case num1: // will produce same bytecode as 

    case 1: // num1 was replaced by compiler 

} 

Compiler kann gleiche über num2 nicht davon ausgehen, wie mit einfachen Beispiel erklärt here

Hinweis, dass Sie gleiches Problem mit num1 haben würden, haben Sie es mit nicht konstanter initialisiert, zum Beispiel: int num1 = new Random().nextInt();