【问题标题】:Java switch : variable declaration and scopeJava switch:变量声明和范围
【发布时间】:2012-06-11 13:51:33
【问题描述】:

Java 编译器如何处理下面的 switch 块? 'b' 变量的作用域是什么?

请注意,“b”变量仅在 switch 语句的第一个分支中声明。尝试在第二个分支中声明它也会导致“重复的局部变量”编译错误。

    int a = 3;
    switch( a ) {
    case 0:
        int b = 1;
        System.out.println("case 0: b = " + b);
        break;
    case 1:
        // the following line does not compile: b may not have been initialized
        // System.out.println("case 1 before: b = " + b);
        b = 2;
        System.out.println("case 1 after: b = " + b);
        break;
    default:
        b = 7;
        System.out.println("default: b = " + b);
    }

注意:以上代码使用 java 1.6 编译器编译。

【问题讨论】:

    标签: java scope initialization switch-statement variable-declaration


    【解决方案1】:

    与往常一样,范围由{} 分隔。

    【讨论】:

    • 给 OP 的消息,您可以在每个案例周围加上大括号,然后它就可以工作了。如case 1: { doHere(); break; }
    【解决方案2】:

    b 的范围是块。您只有一个包含所有cases 的块。这就是为什么在第二个 case 中重新声明 b 时会出现编译错误的原因。

    您可以将每个 case 包装在一个自己的块中,例如

    case 0:
       {
         int b = 1;
         ...
       }
    case 1:
       {
         int b = 2;
         ...
       }
    

    但我认为 FindBugs 或 CheckStyle 会抱怨这一点。

    【讨论】:

    • 编译错误不是来自redeclaring b,而是在初始化之前访问它。 b 在情况 0、1 和默认情况下完全有效,因为正如您提到的那样,它在范围内。他的注释行没有编译的问题是 b 在被访问之前没有被初始化。
    • 我应该更仔细地阅读这个问题。我以为他在注释行中做int b = 2 ;-)
    【解决方案3】:

    您的 case 块没有任何本地范围。它不是一系列if...else if...else 块,java 将其实现为一系列GOTOs。

    【讨论】:

      【解决方案4】:

      b 的作用域是开关块——在声明和分隔符} 之间——

      int a = 3;
      
      switch( a ) {
           case 0:
                int b = 1; //scope starts
                System.out.println("case 0: b = " + b);
                break;
           case 1:
                // the following line does not compile: b may not have been initialized
                // System.out.println("case 1 before: b = " + b);
                b = 2;
                System.out.println("case 1 after: b = " + b);
                break;
           default:
                b = 7;
                System.out.println("default: b = " + b);
      }//scope ends
      

      但是,您需要知道,如果您在 case 1: 中声明 int b,您将无法访问 case 0: 中的变量 b

      要回答您在 java cmets 中提出的问题,您可以查看这个更简单的示例:

      int b;
      if(true){
          b++; //The local variable b hast not been initialized
      }
      

      希望对你有帮助。

      【讨论】:

        【解决方案5】:

        在你的代码中如果 a 不等于 0 b 将永远不会被初始化。你应该在 switch 语句之前定义 b。

        【讨论】:

        • 问题出在编译时,而不是运行时。
        【解决方案6】:

        switch() 语句中定义的变量范围与由{} 包围的普通块中的范围相同。

        因此,switch() 语句中定义的每个变量一旦被定义,对整个块都是可见的。

        【讨论】:

          【解决方案7】:

          您可以在案例周围使用 {} 定义范围。

          int a = 3;
          switch( a ) {
          case 0: {
              int b = 1;
              System.out.println("case 0: b = " + b);
              break;
          }
          case 1: {
              // the following line does not compile: b may not have been initialized
              // System.out.println("case 1 before: b = " + b);
              int b = 2;
              System.out.println("case 1 after: b = " + b);
              break;
          }
          default: {
              int b = 7;
              System.out.println("default: b = " + b);
          }
          }
          

          【讨论】:

            猜你喜欢
            • 2013-11-19
            • 2020-03-18
            • 2014-09-20
            • 1970-01-01
            • 2010-11-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多