Switch语句:常量表达式必需错误

时间:2019-02-24 07:04:03

标签: java switch-statement final

Eclipse显示错误需要常量表达式,但所有字段均为final。那为什么会抛出这个错误。有人可以告诉我我的错误在哪里。

package com.oca.test.exam;

public class Test {

    public static final Integer x1 = 5;
    public static final Integer x2 = 10;
    public static final Integer x3 = 15;
    public static final Integer x4 = 20;

    public static void main(String[] args) {
        switch (x1) {
        case x1: 
            System.out.println();
            break;

        case x2: 
            System.out.println();
            break;

        case x3: 
            System.out.println();
            break;

        case x4: 
            System.out.println();
            break;
        }
    }
}

3 个答案:

答案 0 :(得分:0)

case表达式必须是常量表达式,您可以使用 enum ,这对于常量值和可读性更好的代码来说更好,这是enum的示例:

枚举类:

    public enum Numbers {

    HIGH(3), // calls constructor with value 3
    MEDIUM(2), // calls constructor with value 2
    LOW(1) // calls constructor with value 1
    ; // semicolon needed when fields / methods fol
    private final int levelCode;

    Numbers(int levelCode) {
        this.levelCode = levelCode;
    }

    public int getLevelCode() {
        return this.levelCode;
    }
}

适合您的主要方法:

public class Test {

    public static void main(String[] args) {
        switch (Numbers.HIGH) {
        case HIGH:
            System.out.println("hight");
            break;

        case MEDIUM:
            System.out.println("medium");
            break;

        case LOW:
            System.out.println("low");
            break;

        }

    }
}

答案 1 :(得分:0)

一个TL; DR位于结尾。

查看documentation of the switch statement,我们可以找到以下内容:

  

开关适用于byte,short,char和int基本数据类型。它还适用于枚举类型(在Enum Types中讨论),String类以及一些包装某些基本类型的特殊类:Character,Byte,Short和Integer(在Numbers和Strings中讨论)。

起初这似乎很好,而且您的问题不应该存在。但是,该定义未提及可以在何处使用这些包装器,而在何处不能使用。查看specs of the switch-statements (JLS),我们发现开关的形式为:

1个Switch-Expression

  

SwitchStatement: switch ( Expression ) SwitchBlock

Expression进一步说明:

  

表达式的类型必须为char,byte,short,int,Character,Byte,Short,Integer,String或枚举类型(第8.9节),否则会发生编译时错误。

因此,在这里使用Integer之类的包装器类是完全可以的。编译器将管理。

2个开关块

开关块可细分为:

  

SwitchLabels BlockStatements

SwitchLabel定义为:

  

SwitchLabel: case ConstantExpression : case EnumConstantName : default :

因此,标签将仅接受常量表达式或枚举。如果现在看一下definition of a constant expressions,我们会发现:

  

常量表达式是表示原始类型值或String ...的表达式。

当然,必须满足一些条件才能使基本类型成为常量(在此处列出),但重要的是必须使用基本类型或String。

奖励

包装器类和原始类型之间的交换称为“自动装箱或拆箱”(取决于方向)。根据{{​​3}},拆箱发生在以下情况:

  

将包装类型(Integer)的对象转换为其对应的原始(int)值称为拆箱。当包装类的对象为:

时,Java编译器将应用拆箱。      
      
  • 作为参数传递给期望值的方法   相应的原始类型。
  •   
  • 分配给   相应的原始类型。
  •   

因此看来,似乎Java并非只是为了进行所需的拆箱操作而构建的,以便开关声明如您所愿地起作用。

----------------------

TL; DR

对于switch表达式,您可以使用包装器类。对于标签,您只能使用基本类型:字节,短型,字符和整数。

答案 2 :(得分:-2)

在Java中声明为final的变量不被视为编译时间常数,因为它们的值仍可以在运行时更改-从未定义状态变为已定义状态。

必须在现场定义大小写值,例如。 case 5: case 12: case "green":