Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variables in different switch cases can't have the same name?

I was refactoring some code to make it easier to read and I ran into something that I find weird and I was wondering if anyone could explain this to me.

Original code:

if(tokensLeft == 3) {
  String id = tokens.nextToken();
  String value = tokens.nextToken();
  String trailerId = tokens.nextToken();
  rawListener.binaryInfo(id, Integer.parseInt(value), trailerId, this);
} else if(tokensLeft == 2) {
  String id = tokens.nextToken();
  String value = tokens.nextToken();
  rawListener.binaryInfo(id, Integer.parseInt(value), this);
} else {
  System.out.println("Method call binaryInfo could not be done because: \"Wrong number of parameters\"");
}

After refactoring:

switch(tokensLeft) {
case 3:
  String id = tokens.nextToken();
  String value = tokens.nextToken();
  String trailerId = tokens.nextToken();
  rawListener.binaryInfo(id, Integer.parseInt(value), trailerId, this);
  break;
case 2:
  String id = tokens.nextToken(); // Syntax error
  String value = tokens.nextToken(); // Syntax error
  rawListener.binaryInfo(id, Integer.parseInt(value), this);
  break;
default:
  System.out.println("Method call binaryInfo could not be done because: \"Wrong number of parameters\"");
  break;
}

At first glance this looks perfectly reasonable, but this gives me a syntax error.

Link all references for a local rename (does not change references in other files)

It turns out that for some reason in a switch statement, I am unable to use the String id and String value again in a different case.

This makes naming my variables rather awkward.

Now you could say: "Just declare your variables above your switch statement." But that would mean that I always create my variables, even if tokensLeft is neither 3 or 2 and I wouldn't need my variables. That just feels like using unnecessary memory.

Can anyone explain to me why the switch case does this and how I could solve my problem?

like image 875
JREN Avatar asked Jul 12 '13 07:07

JREN


People also ask

Can two variables of different types have the same name?

Yes, if they are not in the same lexical scope. For example (we have two variables named x , one is the formal int x , and another is the double x in the inside block).

Which variables Cannot be used in switch-case statement?

The switch/case statement in the c language is defined by the language specification to use an int value, so you can not use a float value. The value of the 'expression' in a switch-case statement must be an integer, char, short, long. Float and double are not allowed.

Can we use same constant in two different switch cases?

The switch statement can include any number of case instances. However, no two constant-expression values within the same switch statement can have the same value.

Can you use the same variable name in different functions?

Variables belonging to different functions in a single code can have same name if we declare that variable globally as shown in the following code snippet below .


5 Answers

add {}. try this:

switch(tokensLeft) {
case 3:
{
  String id = tokens.nextToken();
  String value = tokens.nextToken();
  String trailerId = tokens.nextToken();
  rawListener.binaryInfo(id, Integer.parseInt(value), trailerId, this);
}
  break;
case 2:
{
  String id = tokens.nextToken(); // Syntax error
  String value = tokens.nextToken(); // Syntax error
  rawListener.binaryInfo(id, Integer.parseInt(value), this);
}
  break;
default:
  System.out.println("Method call binaryInfo could not be done because: \"Wrong number of parameters\"");
  break;
}
like image 103
yushulx Avatar answered Oct 14 '22 12:10

yushulx


You are redefining variables , that is duplicate variable declaration . case doesn't make a block.

As per JLS 14:

A block is a sequence of statements, local class declarations and local variable declaration statements within braces.

You have two options here:

  1. Define an explicit block under each case using { .. }, though it looks pretty odd I must say.

    OR

  2. In each case you can delegate the logic to a method call .

like image 28
AllTooSir Avatar answered Oct 14 '22 10:10

AllTooSir


Do it as below

  String id;
  String value ;

  switch(tokensLeft) {
  case 3:
     id = tokens.nextToken();
     value = tokens.nextToken();
    String trailerId = tokens.nextToken();
    rawListener.binaryInfo(id, Integer.parseInt(value), trailerId, this);
    break;
  case 2:
     id = tokens.nextToken(); // Syntax error
     value = tokens.nextToken(); // Syntax error
    rawListener.binaryInfo(id, Integer.parseInt(value), this);
    break;
  default:
    System.out.println("Method call binaryInfo could not be done because: \"Wrong number of parameters\"");
    break;
  }

Here it will not cause memory issues as you say. When it executes the method it will keep id and value in the stack and no relevant object in heap for those references. Thus no issue with memory instead the small memory it take for two ref.

like image 22
Sanjaya Liyanage Avatar answered Oct 14 '22 10:10

Sanjaya Liyanage


You can use curly brackets {} after the case:

int aInt = 3;
switch (aInt) {
  case 0:  {
    String text = "";
    break;
  }
  case 1: {
    String text = "";
    break;
  }
}
like image 38
morpheus05 Avatar answered Oct 14 '22 12:10

morpheus05


How about not declaring the variables at all?

switch (tokensLeft) {
    case 3:
        rawListener.binaryInfo(
                tokens.nextToken(),
                parseInt(tokens.nextToken()),
                tokens.nextToken(),
                this);
        break;
    case 2:
        rawListener.binaryInfo(
                tokens.nextToken(),
                parseInt(tokens.nextToken()),
                this);
        break;
    default:
        throw new IllegalArgumentException("Method call binaryInfo could not be done because: \"Wrong number of parameters\"");
}

I added a static import for Integer.parseInt.

Better yet call your logic in well named methods from the switch and declare whatever variables you want:

public void parseTokens() {
    switch (tokensLeft) {
        case 3:
            parseThreeTokens(rawListener, tokens);
            break;
        case 2:
            parseTwoTokens(rawListener, tokens);
            break;
        default:
            throw new IllegalArgumentException("Method call binaryInfo could not be done because: \"Wrong number of parameters\"");
    }
}

public void parseThreeTokens(final RawListener rawListener, final Tokens tokens) {
    final String id = tokens.nextToken();
    final String value = tokens.nextToken();
    final String trailerId = tokens.nextToken();
    rawListener.binaryInfo(id, parseInt(value), trailerId, this);

}

public void parseTwoTokens(final RawListener rawListener, final Tokens tokens) {
    final String id = tokens.nextToken();
    final String value = tokens.nextToken();
    rawListener.binaryInfo(id, parseInt(value), this);
}
like image 26
Boris the Spider Avatar answered Oct 14 '22 10:10

Boris the Spider