8

I was getting this error using Eclipse.

Duplicate local variable cape

I really don't understand why I was getting such an error. This was my code:

switch (frame) {  // frame is an integer
case 0:
    Sprite cape = modules.get(Module.CAPE);
    //cape.setRegion(region);
    cape.translateY(+1);
    break;
case 1:
    Sprite cape = modules.get(Module.CAPE);
    //cape.setRegion(region);
    cape.translateY(-1);
    break;
default:
    throw new IllegalArgumentException(
            "Undefined frame number: " + frame);
}

Why is it not true that the cape variable is local to each case, but instead to the switch statement?

Someone
  • 551
  • 3
  • 14
  • 1
    Good answers have already been provided but to strictly answer your question, consider how the code would behave if you removed the `break` in case 0. – Grambot Mar 13 '14 at 18:34

4 Answers4

19

The whole switch statement is a code block like any other. But you can create code blocks inside code blocks, so:

case 0: {
    // code here
}
case 1: {
    // other code here
}

(if the switch were treated specially in this regard you couldn't be able to do follow through)

fge
  • 119,121
  • 33
  • 254
  • 329
9

Why is it not true that the cape variable is local to each case, but instead to the switch statement?

Because the JLS says so

The scope of a local variable declaration in a block (§14.4) is the rest of the block in which the declaration appears, starting with its own initializer and including any further declarators to the right in the local variable declaration statement.

And about switch

The body of a switch statement is known as a switch block.

A case does not define a scope. It's the switch block that defines a new scope.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
9

Each case is within the same block, specifically, the {} for the switch statement. This is the same block even when different cases define the same variable.

Define your own blocks for each case by adding {}s:

case 0:
  {
    Sprite cape = modules.get(Module.CAPE);
    //cape.setRegion(region);
    cape.translateY(+1);
  }
    break;
case 1:
  {
    Sprite cape = modules.get(Module.CAPE);
    //cape.setRegion(region);
    cape.translateY(-1);
  }
    break;

Or you can simply declare cape before the switch so it's in scope there, where you use the reference.

Sprite cape;
switch (frame) {  // frame is an integer
case 0:
    cape = modules.get(Module.CAPE);

and similarly for case 1.

rgettman
  • 176,041
  • 30
  • 275
  • 357
0

You should declare cape variable outside switch statement:

Sprite cape;
switch (frame) {
    case 0:
        cape = modules.get(Module.CAPE);
        //cape.setRegion(region);
        cape.translateY(+1);
        break;
    case 1:
        cape = modules.get(Module.CAPE);
        //cape.setRegion(region);
        cape.translateY(-1);
        break;
    default:
        throw new IllegalArgumentException(
            "Undefined frame number: " + frame);
}
nikis
  • 11,166
  • 2
  • 35
  • 45
  • 1
    That does not answer my question. – Someone Mar 13 '14 at 18:32
  • @Someone because everything inside switch belong to the same scope – nikis Mar 13 '14 at 18:36
  • @Someone: It does, you just don't realize it – Engineer2021 Mar 13 '14 at 18:43
  • @GIJoe **Why** is it not true that the cape variable is local to each case, but instead to the switch statement? I'm not asking how I can stop getting the error. – Someone Mar 13 '14 at 18:47
  • @Someone: Because the case statements are labels. The compiler defines scope as what is between the switch block (aka the curly braces). The object can't be defined twice in the same block with the same name. It would be the same problem if you had defined it on two different lines in a function. – Engineer2021 Mar 13 '14 at 18:49