Java 变量哲学&x27;switch语句中的s作用域

Java 变量哲学&x27;switch语句中的s作用域,java,switch-statement,language-design,Java,Switch Statement,Language Design,正如在这个问题中所回答的,案例中变量的范围属于整个开关语句本身,而不仅仅是案例。因此,这不会编译(复制局部变量): 我主要对两件事感兴趣 这种行为背后的理念或设计原则是什么?(也许我甚至想问一下切换语句作为一个整体的动机?) 这是怎么发生的?这段代码是如何看待字节码,甚至是汇编级的 在每个case子句周围放一对大括号: int key = 2; switch (key) { case 1: { String str = "1"; return str; } case 2:

正如在这个问题中所回答的,
案例
中变量的范围属于整个
开关
语句本身,而不仅仅是
案例
。因此,这不会编译(复制局部变量):

我主要对两件事感兴趣

  • 这种行为背后的理念或设计原则是什么?(也许我甚至想问一下切换语句作为一个整体的动机?)
  • 这是怎么发生的?这段代码是如何看待字节码,甚至是汇编级的

  • 在每个case子句周围放一对大括号:

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

    这将被编译。

    无论好坏,Java中的
    开关的语义受到C中
    开关的语义的严重影响。虽然我们作为程序员倾向于将大小写标签后跟一些语句和break/continue/return作为一个逻辑单元,但实际上它并不是这样工作的,在语言层面上不存在这样的结构。在
    开关
    中,
    中断
    继续
    只是语句,当执行
    开关
    时,从匹配的案例标签开始执行块的其余部分。碰巧的是,在大多数情况下,您都会遇到一个
    中断
    继续
    返回
    。(见附件)关键句子是:

    开关块中匹配的大小写标签之后的所有语句(如果有)都按顺序执行

    许多人相信(依我看,这是合理的)Java中的
    switch
    语句的优先级是向后的;该语言将故障和其他控制流异常视为正常情况,
    break
    视为例外情况。但当然,在实际代码中,情况正好相反。(Java是如何获得这些向后优先级的?通过从C复制)

    switch语句的作用域规则非常直接地从这个世界观出发;如果一个开关的主体是一个未区分的块,它恰好带有
    case
    标签,那么它当然是一个很大的范围。不要介意,这并不是几乎所有开发人员一直想要的


    除了在默认情况下混淆作用域和故障排除之外,人们对Java中的
    switch
    感到遗憾的是,它只是一个语句,而不是一个表达式。请参阅,它解决了所有这些问题(以向后兼容的方式),这可能是Java12中的预览功能

    从C语言中寻找灵感。(也就是说,认为代码<开关/<代码>语句在哲学上和行为上等同于计算<代码> Goto < /Cord>语句)。至于Q.2,这是你可以用几分钟的工作轻松地回答自己的问题…@米迦勒,因为你自己可以很容易地做到这一点!对于所有其他控制语句,
    if
    else
    for
    while
    等,其工作原理相同。所有这些都不引入新的变量范围;您必须自己使用
    {
    }
    来完成此操作。为什么他们会使
    开关
    有任何不同?@Michael:Java中引入新变量作用域的唯一方法是在花括号内。似乎你是在建议一个switch案例应该引入一个没有花括号的新变量范围——那么这将是Java中唯一的例外——至于为什么,我认为没有人考虑过这样做,因为你总是可以自己使用{Block}引入一个新的变量范围@OliverCharlesworth我特别针对OP的说法,即“
    if,while,
    for
    都引入了范围”。他们没有。例如,单个声明不能是声明声明声明。感谢您抽出时间!也许我的沟通不够强烈,但我在一个switch语句中要求更多关于案例行为动机的信息。链接的答案提供了相同的解决方案。啊,我明白了。好吧,我不认为这是一个很好的理由(用java语言做出的许多设计决策也是如此,这还不是最糟糕的问题)。
    int key = 2;
    switch (key) {
      case 1: {
        String str = "1";
        return str;
      } case 2: {
        String str = "2";
        return str;
      }
    }