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?

1
  • 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. Commented Mar 13, 2014 at 18:34

4 Answers 4

20

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)

Sign up to request clarification or add additional context in comments.

1 Comment

+1 Curly braces define scope. case labels are like a goto.
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.

Comments

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.

2 Comments

Alternately you could define 'Sprite cape' outside of the switch, and then set it in each case.
@Scott Yes, I was getting to that!
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);
}

5 Comments

That does not answer my question.
@Someone because everything inside switch belong to the same scope
@Someone: It does, you just don't realize it
@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: 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.