106

I think I don't understand how the scope works in a switch case.

Can someone explain to me why the first code doesn't compile but the second does ?

Code 1 :

 int key = 2;
 switch (key) {
 case 1:
      String str = "1";
      return str;
 case 2:
      String str = "2"; // duplicate declaration of "str" according to Eclipse.
      return str;
 }

Code 2 :

 int key = 2;
 if (key == 1) {
      String str = "1";
      return str;
 } else if (key == 2) {
      String str = "2";
      return str;
 }

How come the scope of the variable "str" is not contained within Case 1 ?

If I skip the declaration of case 1 the variable "str" is never declared...

Naman
  • 27,789
  • 26
  • 218
  • 353
Philippe Carriere
  • 3,712
  • 4
  • 25
  • 46
  • Made an answer to the original question about the [changes in the local variable scoping and use of switch expressions](https://stackoverflow.com/a/52238424/1746118) with [tag:java-12] – Naman Sep 08 '18 at 19:20

7 Answers7

212

I'll repeat what others have said: the scope of the variables in each case clause corresponds to the whole switch statement. You can, however, create further nested scopes with braces as follows:

int key = 2;
switch (key) {
case 1: {
    String str = "1";
    return str;
  }
case 2: {
    String str = "2";
    return str;
  }
}

The resulting code will now compile successfully since the variable named str in each case clause is in its own scope.

Richard Cook
  • 32,523
  • 5
  • 46
  • 71
  • 10
    Listen to this guy. He's right. – John Oct 09 '10 at 02:26
  • 29
    Correct. But I would be very annoyed with any programmer in my team who uses this "syntax" without a VERY good reason. It's a recipe for confusion and bugs. It visually hides the fact that the first case block (if it not were for the `return`) "continues" even after the closing brace - and helps to forget the `break`. – leonbloy May 18 '11 at 18:16
  • 3
    also: use `break` for maintainability and bug prevention! even if not required. – worenga Nov 28 '14 at 19:26
  • 1
    @mightyuhu break won't work as there is return statement...at least for Java...C or C++ it is fine... – Boy Apr 08 '15 at 19:21
  • 2
    @Boy you are probably right. However, this was not my original point actually. i think those premature returns lead to all kind of maintenance and bug masquerading problems not to mention dead code or cyclomatic complexity. So as a general advice one should avoid such constructs at least in cases that ain't trivial – worenga Apr 08 '15 at 22:55
  • Not only to help visually `break` will help javascript performance in very long switch statements by exiting the statement without evaluating the rest of it ! – Mg Gm Jul 30 '21 at 19:52
  • 1
    @MgGm the question is about Java, not JavaScript. – Henry Jan 18 '22 at 10:04
  • Makes sense even in 2022 :) – Venkatesh Manohar Dec 17 '22 at 04:03
10

The scope of the variable is the whole switch statement -- all cases and default, if included.

Here are some other options...

Option 1:

int key = 2;
switch (key) {
case 1:
     return "1";
case 2:
     return "2";
}

Option 2:

int key = 2;
String str = null;
switch (key) {
case 1:
     str = "1";
     return str;
case 2:
     str = "2";
     return str;
}
Drew Wills
  • 8,408
  • 4
  • 29
  • 40
  • 1
    Option 3: ```java switch (key) { case 1: { String str = "1"; return str; } case 2: { String str = "2"; return str; } } ``` – Ben Jones Dec 22 '21 at 18:37
9

You seem to be assuming that each case is a block with its own local scope, as if/else blocks. It's not.

It's important to correct this conceptual mistake, because otherwise you'll end falling in the frequent trap of forgetting the break inside the case

leonbloy
  • 73,180
  • 20
  • 142
  • 190
2

I think it's a valid question, and scope assumption for case statment is unavoidable. Adjusting ourselves to it because java writer has made this not correct.

e.g. if statement by default take first line in its scope than what's wrong with cases where the end of case is explicitly closed by break statement. Hence the declaration in case 1: should not be available in case 2 and it has parallel scope but not nested.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

Several cases can be executed in one switch statement. So..

Stan Kurilin
  • 15,614
  • 21
  • 81
  • 132
0

The scope of a variable exists between the braces of the switch and if statements. In example Code 1 the switch braces enclose both declarations of the variables which will cause the compiler to error as the name to variable binding will have already been made.

In the other example it is ok because both variables are declared within their own braces (scope).

JB.
  • 871
  • 1
  • 11
  • 19
0

In the first case the scope of the String declaration is within the switch statement therefore it is shown as duplicate while in the second the string is enclosed within curly braces which limits the scope within the if/else conditions,therefore it is not an error in the second case.

Emil
  • 13,577
  • 18
  • 69
  • 108