为什么 switch 语句中的 case 没有自己的作用域?

5

请看下面的代码:

int num = 0;

switch(num) {
   case 1:
      boolean bool = false;
      break;
   case 2:
      String one;
      String two;
      String three;
      //..simulating lots of vars
      break;
   default:
      bool = true;
      System.out.println(bool);
      break;
}

由于我们可以引用在另一个case声明的变量,这意味着即使没有选择case 1boolean bool仍然被声明。

由于default是最后一个选项,而Java从左到右(从上到下)工作,我认为在case 2(和任何其他case)中的变量也将被声明。

这让我想到在选择之前声明的case中有更多代码,与如果首先声明所选的case相比,实际访问该case需要更长的时间

switch语句为什么要这样工作?如果有很多case,使用if-else是否比switch语句更好?(谈论处理时间,纳秒)


6
设计决策。简化落空情况。在作用域情况下添加 {} - Boris the Spider
1
switch (...) { all cases belong to this context }, 然后你也可以使用 case ...: { this case now has own context } ;) - MadProgrammer
1
这里不适用“优化”。任何一种构造方式都可以同样高效地实现。字节码/虚拟机并不像程序员那样关心局部变量。(即Java不会“执行”变量声明。) - user2864740
1
@JonKiparsky 这更多关乎在选择你的情况之前声明了多少变量,而不是情况的数量。 - Dioxin
1
@SanketPipariya 我理解作用域; 我不明白的是,由于我问题中列出的担忧,为什么要这样做。 - Dioxin
显示剩余6条评论
2个回答

3

{ }代表一个作用域,您可以按照任何方式使用它。

在switch语句中:

switch (...) {
}

花括号 { } 内的所有内容都属于同一个作用域。 如果你希望每个 case 都有自己的作用域,需要像这样使用 { } :

switch (...) {
    case 0: {
    }
    break;
    case 1: {
    }
    break;
}

同样地,您可以使用 { } 来声明嵌套作用域,就像这样:
{
      {
          int i;
      }
      {
          int i;
      }
}

我理解作用域的工作原理。我想知道为什么 switch 语句是这样设计的,而不是每个 case 都有自己的作用域,所以这并没有回答我的问题(抱歉)。 - Dioxin
1
我没有设计Java,所以不能确定,但我的猜测是switch语句需要一个{ },为了与表示作用域的'{ }'保持一致,他们需要让它表现出这种方式。考虑if语句。它不需要{ },但它也不允许您在不使用{ }的情况下声明变量:if (true) int x = 0;会抛出语法错误。 - gmarintes
1
@VinceEmigh - 如果你想要在case内部轻松地添加额外的作用域(如本例所示),那么你可以这样做。但是,如果Java语言强制每个case都有额外的作用域,并且你实际上希望多个case共享一个作用域,那该怎么办呢?也就是说,由于语言的限制,你可以实现任一语义(但其中一种需要额外输入{})。 - Damien_The_Unbeliever

2
Java中的switch语句是在C++中的switch语句基础上设计的,而C++的switch语句又是在C语言的switch语句基础上发展起来的,而C语言的switch语句很可能是在B语言或BCPL中得到了启发(这些语言都具有相同的单块结构)...关于这个问题,正如一个失落已久的Sun错误报告所说的那样,“原因在时间的迷雾中失去了”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接