2013-07-12 50 views
5

我正在重构一些代码,以使它更易于阅读,并且遇到了一些我觉得很奇怪的东西,我想知道是否有人可以向我解释这一点。不同交换机机箱中的变量不能具有相同的名称?

原始代码:

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 idString value在另一种情况下。

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

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

任何人都可以向我解释为什么开关盒这样做,我怎么能解决我的问题?

+2

使用方法 - 这是很好的做法反正和你的范围将被分拣为您服务。如果你真的想写意大利面代码,然后使用显式块('{}')。 –

回答

1

如何根本不声明变量?

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

我加了一个static进口的Integer.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); 
} 
+2

我想它会起作用,但当我最初的目标是让它更容易时,它似乎使事情变得不那么容易阅读。 – JREN

+0

在这种情况下创建方法。你的代码不容易阅读 - 最好的做法(和鲍勃叔叔)建议方法应该不超过10行。这个开关块已经接近20个。 –

+0

关于如何区分我创建的两种方法,您有什么建议吗?因为唯一的区别是它们中的一个会使用第三个参数。除此之外,它们是相同的。而且这些方法都只能接受1个paremeter'tokens'。 – JREN

3

就做如下

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和值,并且堆中没有相关对象用于这些引用。因此,没有问题与内存,而不是两个裁判所需的小内存。

+1

请仔细阅读下面我的代码... – JREN

8

您正在重新定义变量,即重复的变量声明。 case不会阻止。每JLS 14

如:

A嵌段是声明,局部类声明和括号内的局部变量声明的语句序列。

你这里有两种选择:

  1. 定义下的每个情况下使用{ .. }明确的块,虽然它看起来 很奇怪,我必须说。

    OR

  2. 在每case可以委派的逻辑到一个方法调用。

+0

但是,这是如何帮助我解决我的问题? – JREN

+3

然后,您可以将逻辑放在每个案例的方法调用中? – NINCOMPOOP

+0

嗯,是的,我现在看到你已经编辑了你的答案:p – JREN

6

add {}。试试这个:

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

很聪明。这应该是正确的答案。它实现了在多个开关情况下使用相同变量名称的目标。 – Thupten

2

可以的情况下使用后大括号{}:

int aInt = 3; 
switch (aInt) { 
    case 0: { 
    String text = ""; 
    break; 
    } 
    case 1: { 
    String text = ""; 
    break; 
    } 
} 
0

caseswitch陈述并非blocks;因此,通过在多个开关情况下声明相同的变量,您试图重新定义变量。这适用于if声明,因为它们形成blocks

要么在开关之前声明它们,要么将块放入您的案例中。

相关问题