7

我正在重构一些代码以使其更易于阅读,并且遇到了一些我觉得很奇怪的东西,我想知道是否有人可以向我解释这一点。

原始代码:

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\"");
}

重构后:

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;
}

乍一看,这看起来非常合理,但这给了我一个语法错误。

链接本地重命名的所有引用(不更改其他文件中的引用)

事实证明,由于某种原因,在 switch 语句中,我无法在不同的情况下再次使用String idand 。String value

这使得命名我的变量相当尴尬。

现在你可以说:“只需在你的 switch 语句之上声明你的变量。” 但这意味着我总是创建我的变量,即使tokensLeft不是 3 或 2 并且我不需要我的变量。感觉就像使用了不必要的内存。

谁能向我解释为什么开关盒会这样做以及如何解决我的问题?

4

6 回答 6

12

您正在重新定义变量,即重复变量声明。case不会阻塞。

根据JLS 14

块是一系列语句、局部类声明和大括号内的局部变量声明语句。

您在这里有两个选择:

  1. 使用 定义每种情况下的显式块{ .. },尽管我必须说它看起来很奇怪。

    或者

  2. 在每一个case中,您都可以将逻辑委托给方法调用。

于 2013-07-12T07:28:09.070 回答
12

添加 {}。试试这个:

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;
}
于 2013-07-12T07:31:39.253 回答
4

如下做

  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;
  }

在这里它不会像你说的那样引起内存问题。当它执行该方法时,它会将 id 和 value 保留在堆栈中,并且在堆中没有这些引用的相关对象。因此,内存没有问题,而是两个参考所需的小内存。

于 2013-07-12T07:27:45.520 回答
3

您可以在大小写后使用大括号 {}:

int aInt = 3;
switch (aInt) {
  case 0:  {
    String text = "";
    break;
  }
  case 1: {
    String text = "";
    break;
  }
}
于 2013-07-12T07:32:13.900 回答
2

根本不声明变量怎么样?

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\"");
}

staticInteger.parseInt.

更好的是在命名方法中调用您的逻辑switch并声明您想要的任何变量:

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);
}
于 2013-07-12T07:33:43.457 回答
0

caseinswitch语句不是blocks;因此,通过在多个 switch 案例中声明相同的变量,您正在尝试重新定义该变量。这在if语句中有效,因为它们形成

要么在切换之前声明它们,要么在你的案例中放置块。

于 2013-07-12T07:33:13.067 回答