4

这是我用 Java 编写的第二个脚本,因为我刚刚开始写一本关于它的书,所以我为这个不可避免的荒谬问题道歉。

我正在编写一个脚本来唱“墙上的 99 瓶啤酒”,并尝试在循环内的条件中声明一个新的 String 变量。不幸的是,它不会编译,因为该字符串据说是未声明的。然后,当我将它从条件中拉出但仍在循环中时,它运行良好。我在这里错过了什么吗?

在职的:

    while (beersLeft >= 0) {
        String sOrNot = "";
        if (beersLeft > 1) {
            sOrNot = "s";
        } else {
            sOrNot = "";
        }
        System.out.println(beersLeft+" bottle"+sOrNot+" of beer on the wall, "+beersLeft+" bottle"+sOrNot+" of beer!");
        System.out.println("Take one down, pass it around, "+beersLeft+" bottle"+sOrNot+" of beer on the wall!");
        System.out.println();

        beersLeft = beersLeft-1;
    }

不工作

    while (beersLeft >= 0) {
        if (beersLeft > 1) {
            String sOrNot = "s";
        } else {
            String sOrNot = "";
        }
        System.out.println(beersLeft+" bottle"+sOrNot+" of beer on the wall, "+beersLeft+" bottle"+sOrNot+" of beer!");
        System.out.println("Take one down, pass it around, "+beersLeft+" bottle"+sOrNot+" of beer on the wall!");
        System.out.println();

        beersLeft = beersLeft-1;
    }

错误:

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous tree type: <any>
at ch01.BottlesOfBeer.main(BottlesOfBeer.java:21)
4

6 回答 6

5

如果您在 if 语句块中定义了字符串,它将不在范围内。

于 2013-04-28T01:28:41.533 回答
5

该问题与可变范围有关。在不工作的示例中,您在 if 和 else 的范围内声明字符串。因此,当您尝试打印这些值时,它们超出了范围。

if (beersLeft > 1) {
    String sOrNot = "s";
    // sOrNot scope ends
} else {
    String sOrNot = "";
    // sOrNot scope ends
}
// sOrNot does not exist in this scope.
System.out.println(beersLeft+" bottle"+sOrNot+" of beer on the wall, "+beersLeft+" bottle"+sOrNot+" of beer!");

工作示例之所以有效,是因为当在循环顶部声明字符串时,它具有贯穿整个事物的范围。

while (beersLeft >= 0) {
   // has scope for rest of loop
   String sOrNot = "";
      ....
}

这种行为可能看起来不直观,但它允许您执行以下操作:

for (int i = 0; i < 10; i++) {
  // do something
}
// The previous i is out of scope, so creates a new one
// without having the names "clash"
for (int i = 5; i >= 0; i--) {
  // do something else
}
于 2013-04-28T01:29:02.073 回答
3

这与范围界定有关。

当您在 if 语句之外声明它时,该声明对整个循环都是可见的。

但是当你在 if 语句块中声明它时,它们只能从内部可见。这就是为什么您稍后会收到未声明的变量错误。

一个简单的说法是,声明只对声明它的最里面的一组括号可见{}

于 2013-04-28T01:28:54.303 回答
3

大括号定义范围。在第二个版本中,变量sOrNot未定义,因为它仅在if语句的范围内定义。

while (beersLeft >= 0) {
    if (beersLeft > 1) {
        String sOrNot = "s";
    } else {
        String sOrNot = "";
    }

    // sOrNot out of scope here - compilation error!
    System.out.println(beersLeft+" bottle"+sOrNot+" of beer on the wall, "+beersLeft+" bottle"+sOrNot+" of beer!");
    ...
 }

在第一个版本sOrNot

于 2013-04-28T01:29:13.903 回答
2

这是 Java 为避免错误而做的事情。这个想法是,如果您只在一个条件语句中为 sOrNot 赋值,而不是在另一个语句中,程序可以运行它的过程并且永远不会为 sOrNot 赋值,但它仍然会尝试打印。如果发生这种情况,程序将出错。

正如其他人所说,这是范围问题,但按照我刚刚定义的方式,新程序员似乎更容易理解。

希望这可以帮助!

于 2013-04-28T01:31:03.597 回答
0

if 语句内部声明的 String sOrNot 只属于 IF 语句,不能在其外部使用。

于 2013-04-28T01:57:44.247 回答