7

Wie behandelt der Java-Compiler den folgenden Switch-Block? Was ist der Gültigkeitsbereich der Variable 'b'?Java-Switch: Variablendeklaration und Gültigkeitsbereich

Beachten Sie, dass die Variable 'b' nur im ersten Zweig der switch-Anweisung deklariert wird. Der Versuch, es auch im zweiten Zweig zu deklarieren, führt zu einem Kompilierungsfehler "doppelte lokale Variable".

int a = 3; 
    switch(a) { 
    case 0: 
     int b = 1; 
     System.out.println("case 0: b = " + b); 
     break; 
    case 1: 
     // the following line does not compile: b may not have been initialized 
     // System.out.println("case 1 before: b = " + b); 
     b = 2; 
     System.out.println("case 1 after: b = " + b); 
     break; 
    default: 
     b = 7; 
     System.out.println("default: b = " + b); 
    } 

Hinweis: Der obige Code kompiliert mit einem Java 1.6-Compiler.

+0

Beantwortete Ihre eigene Frage. – darrengorman

Antwort

21

Der Bereich ist, wie üblich, durch { und } abgegrenzt.

+7

Nachricht an OP, Sie können Klammern um jeden Fall legen und dann würde es funktionieren. Wie im Fall 1: {doHere(); Unterbrechung; } ' – jn1kk

10

Der Umfang von b ist der Block. Sie haben nur einen Block, der alle case s enthält. Deshalb erhalten Sie einen Kompilierungsfehler, wenn Sie b in Ihrem zweiten case dekodieren.

Sie könnten jeden case in einem eigenen Block wickeln wie

case 0: 
    { 
    int b = 1; 
    ... 
    } 
case 1: 
    { 
    int b = 2; 
    ... 
    } 

aber ich denke, FindBugs oder Check würde darüber beschweren.

+4

Der Kompilierfehler stammt nicht von _redeclaring_' b', sondern vom Zugriff vor der Initialisierung. "b" ist perfekt in Fall 0, 1 und Standard, weil, wie Sie erwähnen, es im Umfang ist.Das Problem, dass seine kommentierte Zeile nicht kompiliert wird, ist, dass b vor dem Zugriff nicht initialisiert wurde. – NominSim

+0

Ich hätte die Frage sorgfältiger lesen sollen. Ich dachte, er würde "int b = 2" in der kommentierten Zeile schreiben ;-) – Kai

0

Ihre case Blöcke haben keinen lokalen Gültigkeitsbereich. Es ist nicht eine Reihe von if ... else if ... else Blöcke, Java implementiert es als eine Reihe von GOTO s.

3

Der Umfang der b ist der Schaltblock - zwischen der Deklaration und der Begrenzer } -

int a = 3; 

switch(a) { 
    case 0: 
      int b = 1; //scope starts 
      System.out.println("case 0: b = " + b); 
      break; 
    case 1: 
      // the following line does not compile: b may not have been initialized 
      // System.out.println("case 1 before: b = " + b); 
      b = 2; 
      System.out.println("case 1 after: b = " + b); 
      break; 
    default: 
      b = 7; 
      System.out.println("default: b = " + b); 
}//scope ends 

Allerdings müssen Sie das wissen, ob Sie die int b innerhalb des case 1: erklären, erhalten Sie Zugang nicht haben wird die Variable b innerhalb des case 0:

Um die Frage zu beantworten, die Sie in der Java-fragen Kommentare können Sie dieses einfacheres Beispiel überprüfen:

int b; 
if(true){ 
    b++; //The local variable b hast not been initialized 
} 

Hoffe es hilft.

1

in Ihrem Code, wenn a ungleich 0 b ist, wird niemals initialisiert. Sie sollten b vor der switch-Anweisung definieren.

+0

Das Problem ist zur Kompilierzeit, nicht zur Laufzeit. –

0

Der Umfang der Variablen in einer switch() Anweisung definiert wäre dieselbe wie in einem normalen Block wich sein durch { und } umgeben ist.

Daher ist jede in einer switch()-Anweisung definierte Variable für den gesamten Block sichtbar, sobald sie definiert ist.

3

Sie können den Geltungsbereich mit {} in Ihrem Fall definieren.

int a = 3; 
switch(a) { 
case 0: { 
    int b = 1; 
    System.out.println("case 0: b = " + b); 
    break; 
} 
case 1: { 
    // the following line does not compile: b may not have been initialized 
    // System.out.println("case 1 before: b = " + b); 
    int b = 2; 
    System.out.println("case 1 after: b = " + b); 
    break; 
} 
default: { 
    int b = 7; 
    System.out.println("default: b = " + b); 
} 
}