6

为什么,在 Java 中,变量的范围仅限于 switch 块而不是 case 块。例如,

// Scope limited to a switch block
switch (number) {
case 1:
    String result = "...";
    break;
case 2:
    result = "...";
    break;

在上面的例子中,result 只需要声明一次。如果您声明它两次,那么您会收到一条Duplicate local variable消息。

我的问题是:程序怎么知道你已经声明了resultif number = 2?(它不会落入case 1也不会声明变量......或者会吗?)

编辑:

我可能会让大家感到困惑。我了解如何限制变量的范围,但我的问题是:如果结果不属于这种情况,Java 如何知道结果已被声明

4

7 回答 7

6

编辑:Java 使用词法范围(也称为静态范围),因此变量的范围是在编译时确定的,与实际评估无关。

Java 是块作用域的,因此它的作用域将尊重{}上面示例中的。

JLS 6.3

块中局部变量声明的范围(第 14.4 节)是声明出现的块的其余部分,从它自己的初始化程序开始,并在局部变量声明语句的右侧包括任何进一步的声明符。

于 2013-03-13T22:12:18.630 回答
5

您可以通过添加大括号将范围限制为 case 块,如下所示:

// Scope limited to a switch block
switch (number) {
case 1:{
    String result = "...";
    break;
}
case 2:{
    String result = "...";
    break;
}
于 2013-03-13T22:14:36.177 回答
3

在祖父语言 Fortran 中,有一个计算的 GOTO 语句

        GOTO expr
        ...
    1   ...
        ...
    2   ...
        ...

根据 的值expr,代码跳转到 1、2 等。

C(和Java)的switch语句基本上是变相的计算GOTO。我们有一段带有一些标签的连续代码,我们跳转到其中一个标签。如果没有break,我们将执行该块的其余部分。

这种相当低级的控制机制与当今程序员的直觉相反;我们会认为 switch 语句选择一个子句并执行该子句,就像一个if-elseif-elseif-...-else 语句。

Java 继承了 C 的 switch 语义,因为它们不想过多地偏离 C。较新的语言不太可能继续这个错误。

于 2013-03-13T22:44:29.233 回答
2

Java 使用块作用域,选择案例不是块(它们更像标签)。不过,这会起作用:

switch (key) {
case 1: {
    String result = "1";
    return result ;
  }
case 2: {
    String result = "2";
    return result ;
  }
}
于 2013-03-13T22:12:25.977 回答
2

你是什​​么意思?为了理解答案,您需要了解编译器的工作原理。将 switch 视为一个大块,在每个 switch 语句的末尾有多个“goto”语句。

我不确定 java unroll switch 语句是如何展开的,但一种简单易行的方法是(伪字节码):

    if (number == 1) goto label1;
    if (number == 2) goto label2;
    goto labelEnd;
label1:
    String result = "...";
    goto labelEnd;
label2:
    result = "...";
    goto labelEnd;
labelEnd:
    <some code>
于 2013-03-13T22:16:17.200 回答
0

变量作用域被限制在 switch 块而不是 case 块的原因是 java 允许从一个 case 块跌落到下一个,即

switch (number) {
case 1:
     .... some code ...
case 2:
     .... some more code ...

在这种情况下,如果 number 为 1,则执行 case 1 和 case 2。中断就像选择的 goto 结束,它永远不会结束范围。变量范围必须处于选择级别

正如其他人所说,使用块来限制范围,即

switch (number) {
case 1:{
    String result = "...";
    break;
}
case 2:{
    String result = "...";
    break;
}
于 2013-03-13T23:03:53.583 回答
0

因为没有“案例块”。

Everything inside the switch statement is in the same block. You can't declare the same variable twice in the same block.

If you want a 'case block' you have to write the { and } yourself.

于 2013-03-14T04:35:31.993 回答