没有大括号的if子句的奇数编译器错误

时间:2010-03-27 03:14:27

标签: java compiler-construction curly-braces

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

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

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

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

6 个答案:

答案 0 :(得分:11)

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

OTOH,当你打开一个区块时,做同样的事情(起初)仍然没有任何意义。但是,我们希望你以后能够扩展这个块,并且它最终会有意义。

答案 1 :(得分:4)

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

答案 2 :(得分:2)

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

  

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

换句话说,局部变量声明只能在紧邻块({})的“级别”下显示为独立声明。它们不算作Statements(§14.5),这是if (....)之后的事情。

答案 3 :(得分:1)

问题在于:

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

...基本上等同于:

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

您已经定义并初始化了items,但是当您退出语句/阻止它超出范围时,您实际上无法将其用于任何事情。编译器正在警告你。

答案 4 :(得分:0)

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

编辑:太慢......

答案 5 :(得分:0)

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

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

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之前有一些语言,其范围应该是与return语句相同的级别。是的,按照今天的标准疯狂的语言,但它们仍然存在。