为什么Java中的switch语句的范围不受限制?

时间:2013-03-13 22:11:19

标签: java switch-statement scope language-design

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

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

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

我的问题是:如果result,该程序如何知道您已宣布number = 2? (它不会落入case 1并且不会声明变量......或者它会吗?)

编辑:

我可能会让所有人感到困惑。我理解如何限制变量的范围,但我的问题是:如果结果不属于,Java如何知道结果已被声明?

7 个答案:

答案 0 :(得分:6)

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

Java是块范围的,因此它的范围将尊重上例中的{}

请参阅JLS 6.3

  

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:3)

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

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

基于expr的值,代码跳转到1,2等。

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

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

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

答案 3 :(得分:2)

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

switch (key) {
case 1: {
    String result = "1";
    return result ;
  }
case 2: {
    String result = "2";
    return result ;
  }
}

答案 4 :(得分:2)

你是什么意思?为了理解答案,您需要了解编译器的工作原理。 可以将交换机视为一个大块,在每个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>

答案 5 :(得分:0)

变量范围被限制在开关块而不是case块的原因是java允许从一个case块到另一个case块,即

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

在这种情况下,如果数字是1,则情况1和1都是案例2被执行。 break就像select的goto结尾,它永远不会结束范围。变量范围必须为选择级别

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

switch (number) {
case 1:{
    String result = "...";
    break;
}
case 2:{
    String result = "...";
    break;
}

答案 6 :(得分:0)

因为没有'case block'。

switch语句中的所有内容都在同一个块中。您不能在同一个块中两次声明相同的变量。

如果你想要一个'case block',你必须自己写{}