Switch语句:常量表达式需要错误[重复]

问题描述 投票:0回答:3

这个问题在这里已有答案:

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;
        }
    }
}
java switch-statement final
3个回答
0
投票

case表达式必须是常量表达式,你可以使用枚举它更好地用于常量值和更可读的代码,这是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;

        }

    }
}

0
投票

TL; DR在最后。

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

交换机使用byte,short,char和int原始数据类型。它也适用于枚举类型(在枚举类型中讨论),String类,以及一些包含某些基本类型的特殊类:Character,Byte,Short和Integer(在Numbers和Strings中讨论)。

起初这似乎很好,你的问题不应该存在。但是,该定义没有提到可以使用这些包装器的位置,也没有提到。查看specs of the switch-statements (JLS),我们发现交换机具有以下形式:

1 Switch-Expression

SwitchStatement: switch ( Expression ) SwitchBlock

Expression进一步解释:

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

所以在这里,使用包装类如Integer是完全没问题的。编译器将管理。

2 Switch-Block

开关块可以分解为:

SwitchLabels BlockStatements

SwitchLabel定义为:

SwitchLabel: case ConstantExpression : case EnumConstantName : default :

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

常量表达式是表示基本类型或String的值的表达式...

当然,有些条件必须适用于使原始类型成为常量(在那里列出),但在您的情况下,重要的部分是您必须使用基本类型或字符串。

奖金

包装器类和基本类型之间的交换称为“自动装箱或拆箱”(取决于方向)。根据documentation,拆箱发生在:

将包装类型(Integer)的对象转换为其对应的基元(int)值称为拆箱。当包装类的对象是:时,Java编译器应用拆箱:

  • 作为参数传递给期望相应基元类型的值的方法。
  • 分配给相应基元类型的变量。

因此,似乎Java并不是为了使switch语句按照您的意图进行必要的拆箱而构建的。

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

TL; DR

对于switch表达式,您可以使用包装器类。但是对于标签,您只能使用基本类型:byte,short,char和int。


-2
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.