5

以下 Java 代码引发编译器错误:

if ( checkGameTitle(currGame) )
    ArrayList<String> items = parseColumns( tRows.get(rowOffset+1), currGame, time, method );

checkGameTitle是一个公共静态函数,返回一个布尔值。错误都是“找不到符号”类型,符号为 variable ArrayList,variable Stringvariable items

但是,如果我添加 {花括号} 则代码编译没有错误。为什么会这样?没有它们的条款是否有一些歧义if

4

6 回答 6

11

如果items此时声明一个变量,则无法从任何地方访问它。因此,允许这种构造是没有意义的。

OTOH,当您打开一个块时,(起初)做同样的事情仍然没有意义。但可以预料的是,您稍后会想要扩展该块,并且它最终会有意义。

于 2010-03-27T03:21:26.770 回答
4

使用花括号,您可以创建一个可以包含声明的块。没有大括号,你只能有一个声明,而不是一个声明,比如你的例子

于 2010-03-27T03:25:27.683 回答
2

正因为我认为它在这些情况下总是有帮助的,所以这里 Java 语言规范的相关部分是§14.4

每个局部变量声明语句都立即包含在一个块中。局部变量声明语句可以与块中的其他类型的语句自由混合。

换句话说,局部变量声明只能作为独立声明出现在块({})“下方”的级别。它们不计入Statements(§14.5),这是后面的事情if (....)

于 2010-03-27T10:52:12.983 回答
1

问题在于:

if ( condition )
    ArrayList<String> items = ...;

...本质上等同于:

if ( condition ) {
    ArrayList<String> items = ...;
}

您已经定义并初始化items了 ,但是当您退出语句/块时,它会立即超出范围,因此您实际上不能将它用于任何事情。编译器正在警告您。

于 2010-03-27T03:47:43.067 回答
0

items在 if 语句中定义变量,因此它不能在该范围之外的任何地方使用。

编辑:太慢了...

于 2010-03-27T03:24:55.540 回答
0

编译器错误是因为语言规则没有明确指出“items”变量声明的范围。

例如,如果我有这样的代码块:

bool isTrue() {
  bool returnValue = false;
  if (cheese.isGreen()) {
    returnValue = true;
  }
  return returnValue;
}

很明显,returnValue 是整个方法中的一个有效变量。

如果我有这样的代码块:

bool isTrue() {
  if (cheese.isGreen()) {
    bool returnValue = true;
  }
  return returnValue;
}

很明显,returnValue 在“if 子句”之外是无效的。

但是,如果我有这样的代码块:

bool isTrue() {
  if (cheese.isGreen())
    bool returnValue = true;
  return returnValue;
}

不清楚 returnValue 是否在 if 语句的范围内,或者 returnValue 是否在整个方法的范围内。这是由于 Java 语言语法的布局细节造成的。基本上,允许在任何块中声明新变量(因为块清楚地定义了变量的范围)但是这个 if 语句不包含块。

如果您假设 Java 会默默地为您添加块,那么范围就在“被遗忘的块”内。如果您假设由于没有明确的块来包含范围,那么变量的范围与方法的其余部分处于同一级别。关于哪种观点“更”正确的争论比比皆是,因此禁止这样做的整个尝试。

如果这对您来说很奇怪,并且您认为只有疯子才会认为变量是在隐含块的范围内定义的,请记住在 Java 之前的语言中,范围会处于同一级别作为返回语句。是的,按照今天的标准,疯狂的语言,但它们仍然存在。

于 2010-03-27T05:26:04.037 回答