为什么Java中的Switch语句可以包含一个FINAL变量作为CASE?

时间:2013-02-24 15:32:47

标签: java variables switch-statement case final

为什么Java中的Switch语句可以包含一个FINAL变量作为CASE? ##

在我检查的JDK7中,无法将值重新分配给最终变量,如下所示。但是,为什么最后的变量" x"可以包含在一个案例事件的Switch语句中,以及最终变量" x"不能重新分配?

为什么可以这样做,尽管Oracle定义Java编译器将最终变量作为初始值而不是变量名称?http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4

请告诉我这是否是Java编译器的技术错误,或者是否存在异常或特殊用途检查Switch语句中的最终变量的大小写?

class Example{
    public static void main(String args[]){
        final int x=100;
        //x=200;    //error: cannot assign a value to final variable x

        //The below piece of code compiles
        switch(x){
            case 200: System.out.println("200");
            case 300: System.out.println("300");
        }

    }
}

6 个答案:

答案 0 :(得分:4)

这种情况怎么样?

public class Foo
{
    private final int x;

    public Foo(int x){this.x = x;}

    public void boo()
    {
        switch(x)
        {
            case 200: System.out.println("200");
            case 300: System.out.println("300");
        }
    }
}

或者也许是这个:

public static void doSomething(final int x)
{
    switch(x)
    {
        case 200: System.out.println("200");
        case 300: System.out.println("300");
    }
}

答案 1 :(得分:3)

switch(x){
    case 200: System.out.println("200"); break;
    case 300: System.out.println("300");
}

基本上意味着

if (x == 200)
  System.out.println("200");
else if (x == 300)
  System.out.println("300");

它只是比较,而不是分配,因此x无法修改的事实并不重要。

从技术上讲,你的例子会有所不同(因为你没有break):

if (x == 200)
  System.out.println("200");
if (x == 200 || x == 300)
  System.out.println("300");

或类似的东西。

x永远不能200300的事实并不能使代码无法编译。但是,它可以允许Java优化switch语句。

答案 2 :(得分:2)

好吧,您可以在函数中传递final参数:

//the function doesn't know what x  value is,
//but it knows that it can't modify its value
public someFunction(final int x) {

    x += 1; //compiler error
    switch(x) {
        case 200: System.out.println("200");
            break;
        case 300: System.out.println("300");
            break;
    }
}

//the function doesn't know what x value is,
//but it knows that it can modify it
//for internal usage
public someOtherFunction(int x) {

    switch(x) {
        case 200:
            x += 200;
            break;
        case 300:
            x += 300;
            break;
    }
    System.out.println(x);
}

答案 3 :(得分:1)

为什么期望final修饰符有所作为?不需要为正在打开的值分配任何内容。

您确定了解switch声明的作用吗?

答案 4 :(得分:1)

我认为删除或警告switch的优化 - 编译时已知的语句总是被评估到同一个案例,这在编译器中根本没有实现,因为这是一种罕见的情况。 / p>

以下代码也会在没有警告或错误的情况下编译。

  switch(3){
    case 2: 
      System.out.println("two"); 
      break;
    case 3: 
      System.out.println("three"); 
      break;
  }

编译器关于case 2:部分中无法访问的代码的警告会很好,但是没有实现。

答案 5 :(得分:0)

除了具有最终参数之外,最终的局部变量可以保存在编译时未知的值:

public static void main(String args[]){
    final int x;

    if (someMethod())
      x = 200;
    else
      x = 300;

    switch(x){
        case 200: System.out.println("200");
        case 300: System.out.println("300");
    }

}