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

发布于 2024-08-26 18:04:31 字数 421 浏览 9 评论 0 原文

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

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

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

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

The following Java code is throwing a compiler error:

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

checkGameTitle is a public static function, returning a boolean. The errors are all of the type "cannot find symbol" with the symbols being variable ArrayList, variable String and variable items.

However, if I add {curly braces} then the code compiles with no errors. Why might this be? Is there some ambiguity on the if clause without them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

百合的盛世恋 2024-09-02 18:04:31

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

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

If you declare a variable items at this point, it's not accessible from anywhere. So it would make no sense to allow this construct.

OTOH, when you open a block, it still makes no sense to do the same thing (at first). But it's expected, that you'll want to extend the block later, and that it will eventually make sense.

追我者格杀勿论 2024-09-02 18:04:31

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

With curly braces, you create a block that can contain declarations. Without the braces, you can only have a statement, not a declaration, such as your example

下雨或天晴 2024-09-02 18:04:31

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

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

换句话说,局部变量声明只能作为独立声明出现在紧邻块“下方”的级别 ({})。它们不被视为语句 (§14.5),它们是在if (....) 之后的内容。

Just because I think it's always helpful in these situations, the relevant part of the Java Language Specification here is §14.4:

Every local variable declaration statement is immediately contained by a block. Local variable declaration statements may be intermixed freely with other kinds of statements in the block.

In other words, local variables declarations may only appear as standalone declarations at the level immediately 'below' a block ({}). They are not counted as Statements (§14.5), which are the things that go after if (....).

享受孤独 2024-09-02 18:04:31

问题是:

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

...本质上等同于:

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

您已经定义并初始化了 items,但是当您退出语句/块时,它会立即超出范围,因此您可以'实际上并没有用它来做任何事情。编译器正在警告您这一点。

The problem is that this:

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

...is essentially equivalent to this:

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

You've defined and initialized items, but when you exit the statement/block, it immediately goes out of scope, so you can't actually use it for anything. The compiler is warning you about that.

兔小萌 2024-09-02 18:04:31

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

编辑:太慢了...

You're defining the variable items in the if statement, so it won't be usable from anywhere outside that scope.

EDIT: Too slow...

剩一世无双 2024-09-02 18:04:31

编译器错误是因为语言的规则没有明确指出“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 之前的语言中,范围将处于同一级别作为返回语句。是的,按照今天的标准来看,这是疯狂的语言,但它们仍然存在。

The complier error is because the rules of the language doesn't make a clear point on the scope of the variable declaration of "items".

For example, if I have a block of code like this:

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

it is painfully clear that returnValue is a valid variable across the entire method.

If I have a block of code like this:

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

it is painfully clear that returnValue is not valid outside of the "if clause".

But if I have a block of code like this:

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

it is not clear if returnValue is within the scope of the if statement or if returnValue is within the scope of the entire method. This is due to the details of the layout of the Java language grammar. Basically, it's allowed to declare new variables within any block (because a block clearly defines scope of the variable) but this if statement doesn't contain a block.

If you assume that Java adds the block for you silently, then the scope is within the "forgotten block". If you assume that since there's not explicit block to contain the scope, then the scope of the variable is at the same level as the rest of the method. Arguments abound as to which viewpoint is "more" correct, so the entire attempt to do such a thing is forbidden.

If this seems odd to you, and you thing that only a crazy man would not assume that the variable is defined within the scope of an implied block, please remember that there were languages prior to Java where the scope would have been at the same level as the return statement. Yes, crazy languages by today's standards, but they still existed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文