代码之家  ›  专栏  ›  技术社区  ›  DisgruntledGoat

不带大括号的if子句出现奇数编译器错误

  •  5
  • DisgruntledGoat  · 技术社区  · 15 年前

    下面的Java代码正在引发编译器错误:

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

    checkGameTitle 是公共静态函数,返回布尔值。所有的错误都是“找不到符号”类型,而符号是 variable ArrayList , variable String variable items .

    但是,如果我添加{curly braces},那么 代码编译没有错误 . 为什么会这样?是不是有些模棱两可的地方 if 没有他们的条款?

    6 回复  |  直到 6 年前
        1
  •  11
  •   Chris Lercher    15 年前

    如果你声明一个变量 items 在这一点上,任何地方都无法访问它。所以允许这种构造是没有意义的。

    哦,当你打开一个街区,做同样的事情仍然没有意义(起初)。但预计你以后会想要扩展这个块,而且它最终会有意义的。

        2
  •  4
  •   Chris Dodd    15 年前

    使用大括号,可以创建包含声明的块。没有大括号,您只能有一个语句,而不能有一个声明,例如您的示例

        3
  •  2
  •   Cowan    15 年前

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

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

    换句话说,局部变量声明只能作为独立声明出现在块的“下面”级别( {} )他们不算 Statements (§14.5),这是我们所追求的 if (....) .

        4
  •  1
  •   Scott Smith    6 年前

    问题是:

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

    ……基本上等同于:

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

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

        5
  •  0
  •   Riley Adams    15 年前

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

    编辑:太慢…

        6
  •  0
  •   Edwin Buck    15 年前

    编译器的错误是因为语言的规则没有明确指出“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语句的范围内,或者是否在整个方法的范围内。这是由于Java语言文法布局的细节。基本上,允许在任何块中声明新变量(因为块清楚地定义了变量的范围),但是这个if语句不包含块。

    如果你假设Java悄悄地为你添加了块,那么范围在“被遗忘的块”内。如果假设没有包含作用域的显式块,则变量的作用域与方法的其余部分处于同一级别。关于哪种观点“更”正确的争论很多,因此禁止做这种事情的全部企图。

    如果这对你来说是奇怪的,而你认为只有一个疯狂的人不会假设变量是在隐含块的范围内定义的,那么请记住,Java之前有语言,其范围将与返回语句处于相同的级别。是的,按照今天的标准,疯狂的语言仍然存在。