[英]Odd compiler error on if-clause without braces
以下 Java 代码引发编译器错误:
if ( checkGameTitle(currGame) )
ArrayList<String> items = parseColumns( tRows.get(rowOffset+1), currGame, time, method );
checkGameTitle
是一个公共静态函数,返回一个布尔值。 错误都是“找不到符号”类型,符号是variable ArrayList
、 variable String
和variable items
。
但是,如果我添加 {curly括号} 则代码编译没有错误。 为什么会这样? if
没有它们, if
子句是否存在一些歧义?
如果此时声明变量items
,则无法从任何地方访问它。 因此,允许这种构造是没有意义的。
OTOH,当你打开一个块时,做同样的事情(一开始)仍然没有意义。 但可以预料的是,您稍后会想要扩展该块,并且最终会有意义。
使用花括号,您可以创建一个可以包含声明的块。 没有大括号,你只能有一个声明,而不是一个声明,比如你的例子
仅仅因为我认为它在这些情况下总是有帮助的,这里 Java 语言规范的相关部分是§14.4 :
每个局部变量声明语句都立即包含在一个块中。 局部变量声明语句可以与块中的其他类型的语句自由混合。
换句话说,局部变量声明可能仅作为独立声明出现在紧接“低于”块 ( {}
) 的级别。 它们不算作Statements
(第 14.5 节),它们是if (....)
。
问题在于:
if ( condition )
ArrayList<String> items = ...;
...本质上等同于:
if ( condition ) {
ArrayList<String> items = ...;
}
您已经定义并初始化了items
,但是当您退出语句/块时,它会立即超出范围,因此您实际上无法将其用于任何事情。 编译器正在警告你。
您在 if 语句中定义了变量items
,因此在该范围之外的任何地方都无法使用它。
编辑:太慢了...
编译器错误是因为语言规则没有明确指出“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 之前的语言中,范围会在同一级别作为返回语句。 是的,按照今天的标准是疯狂的语言,但它们仍然存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.