Michael
Michael

Reputation: 2773

Philosophy of variable's scope in a switch statement

As answered in this question here, the scope of a variable inside of a case belongs to the entire switch statement itself, not just the case. Therefore, this does not compile (duplicate local variable):

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

I'm interested in mainly two things...

  1. What's the philosophy, or design principle, behind this behavior? (Maybe I'm even asking for the motivation for the switch statement as a whole?)
  2. How does this happen? How does this code look at the bytecode, or even assembly, level?

Upvotes: 2

Views: 250

Answers (2)

Brian Goetz
Brian Goetz

Reputation: 95326

For better or worse, the semantics of switch in Java were heavily influenced by the semantics of switch in C. And, while we as programmers tend to think of a case label followed by some statements and a break/continue/return as a logical unit, that's not actually how it works, and no such construct exists at the language level. In a switch, break and continue are just statements, and when you execute a switch, you start at the matching case label and execute the remainder of the block. It just so happens that most of the time, you'll hit a break or continue or return before that happens. (See JLS 14.11.) The key sentence is:

All statements after the matching case label in the switch block, if any, are executed in sequence.

Many people believe (IMO, reasonably so) that the switch statement in Java has its priorities backwards; the language treats fallthrough and other control flow oddities as if they were normal case, and break as the exceptional case. But of course, in real code, it's the other way around. (How did Java acquire these backward priorities? By copying from C.)

The scoping rule for switch statements flows pretty directly from this view of the world; if the body of a switch is an undifferentiated block that happens to be peppered with case labels, of course its one big scope. Never mind that this is not actually what almost all developers want almost all the time.

In addition to confusing scoping and fallthrough-by-default, Among the other things people regret about switch in Java is that it is only a statement, not an expression. See JEP 325, which addresses all of these problems (in a backward-compatible way), which will likely be a preview features in Java 12.

Upvotes: 5

Dima
Dima

Reputation: 40500

Just put a pair of braces around each case clause:

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

This will compile.

Upvotes: -3

Related Questions