【问题标题】:Why don't cases in switch statements have their own scope? [duplicate]为什么 switch 语句中的 case 没有自己的范围? [复制]
【发布时间】:2025-12-20 19:55:06
【问题描述】:

考虑这段代码:

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 1 未被选择,boolean bool 仍被声明。

由于default 是最后一个选项,并且java 从左到右(从上到下)工作,我假设case 2(以及任何其他情况)中的变量也将被声明。

这让我觉得在选择案例之前声明的案例中的代码越多,与 if 相比,实际访问该案例所需的时间就越长选择的案例首先被宣布。

switch 语句以这种方式工作是否有特定原因?如果有很多情况,最好使用if-else 而不是 switch 语句? (通话处理时间,纳秒)

【问题讨论】:

  • 设计决策。简化通过案例。将{} 添加到范围案例。
  • switch (...) { all cases belong to this context },那么你也可以使用case ...: { this case now has own context } ;)
  • “优化”不适用于此处。任何一种结构都可以同样有效地实施。字节码/VM 根本不像程序员那样关心局部变量。 (即,Java 不会“执行”变量声明。)
  • 如果您的交换机中有足够多的案例来改变运行时间,那么一定是出了严重的问题。但是,开关通常比 if 链更快,因为它们编译为精心制作的查找表,并且不作为决策序列进行评估。 (这就是为什么你不能打开比较,而只能打开值)

标签: java switch-statement micro-optimization


【解决方案1】:

Java 中的 Switch 语句是在 C++ 中的 switch 语句在 C 中的 switch 语句之后的模式之后被模式化的>

正如一份失传已久的 Sun 错误报告(关于其他内容)所说,“原因已消失在时间的迷雾中”。

【讨论】:

    【解决方案2】:

    { } 代表一个范围,你可以以任何你喜欢的方式使用它。

    在 switch 语句中:

    switch (...) {
    }
    

    {} 中的所有内容都属于同一范围。 如果你想让案例有自己的范围,你需要像这样使用 { }:

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

    同样,您可以使用 { } 在这样的范围内声明范围:

    {
          {
              int i;
          }
          {
              int i;
          }
    }
    

    【讨论】:

    • 我了解示波器的工作原理。我想知道为什么 switch 语句是这样设计的,而不是每个案例都有自己的范围,所以这不能回答我的问题(对不起)
    • 我没有设计java所以我不能确定,但​​我的猜测是switch语句需要一个{},并且为了与代表一个范围的'{}'保持一致,他们需要让它表现得这样。考虑 if 语句。它不需要 { },但它也不允许您在不使用 { } 的情况下声明变量: if (true) int x = 0;引发语法错误。
    • @VinceEmigh - 您可以轻松地在cases 中添加额外的范围,如果这是您想要做的(如图所示)。但是,如果 java 语言为每个 case强制 额外的范围,而您实际上 想要 多个 cases 共享一个范围,你会怎么做?也就是说,就像语言一样,您可以实现任一语义(但需要额外输入{}s)。