Java 枚举:重构 switch 语句“需要常量表达式”编译错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4277819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:17:07  来源:igfitidea点击:

Java enum : Refactoring switch statements 'constant expression required' compile error?

java

提问by emeraldjava

I have a class declaring constants for my app

我有一个类为我的应用程序声明常量

public class GroupConstants {
    ..
    public static final int INTEGER_VALUE = 1;
    public static final int LONG_VALUE = 2;
    public static final int STRING_VALUE = 3;
    ..
}

In the code there is a set of switch statements

代码中有一组switch语句

private static Object getValue(String stringValue, Parameter parameter) throws InvalidPatternException
{
    Object result=null;
    switch (parameter.getDataType())
    {
        case GroupConstants.STRING_VALUE: // String value
            result=stringValue;
        break;
        case GroupConstants.INTEGER_VALUE: // Long value
        case GroupConstants.LONG_VALUE:
        case GroupConstants.BOOLEAN_VALUE:
        case GroupConstants.DATE_VALUE:
..
}

I want to refactor the int constant values to be represented by an enum

我想重构由枚举表示的 int 常量值

public enum DataType {

    UNKNOWN_VALUE(0,"unknown"),
    INTEGER_VALUE(1,"integer"),
    LONG_VALUE(2,"long"),
    STRING_VALUE(3,"string"),
    BOOLEAN_VALUE(4,"boolean"),
..
}

so my code might look like this

所以我的代码可能看起来像这样

@Deprecated
public static final int INTEGER_VALUE = DataType.INTEGER_VALUE.getId();

and overtime i can change my switch statements. When i change the static final int reference to point to the enum all my switch statements break.

加班我可以更改我的 switch 语句。当我将静态最终 int 引用更改为指向枚举时,我所有的 switch 语句都会中断。

[javac] /home/assure/projects/tp/main/src/a/b/c/DDDDDManagerBean.java:1108: constant expression required
[javac]             case GroupConstants.INTEGER_VALUE:
[javac]                                ^
[javac] /home/assure/projects/tp/main/src/a/b/c/ParameterComponent.java:203: constant expression required
[javac]         case GroupConstants.INTEGER_VALUE:
[javac]                            ^
[javac] /home/assure/projects/tp/main/src/a/b/c/ParameterComponent.java:268: constant expression required
[javac]             case GroupConstants.INTEGER_VALUE:
[javac]                                ^
[javac] /home/assure/projects/tp/main/src/a/b/c/ParameterComponent.java:316: constant expression required
[javac]             case GroupConstants.INTEGER_VALUE:
[javac]                                ^
[javac] /home/assure/projects/tp/main/src/a/b/c/ParameterComponent.java:436: constant expression required
[javac]         case GroupConstants.INTEGER_VALUE:

I don't want to be forced to change all the switches yet, so its there a clean work around?

我还不想被迫更改所有开关,所以它有一个干净的解决方法吗?

采纳答案by Stephen C

That won't work. The problem is that the getId()call means that the constant's value expression is not a compile-time constant expression according to the JLS. Refer to JLS 15.28 Constant Expressionsfor the gory details, and you will see that method calls are not allowed in constant expressions.

那行不通。问题在于,getId()根据 JLS ,调用意味着常量的值表达式不是编译时常量表达式。有关详细信息,请参阅JLS 15.28 常量表达式,您将看到常量表达式中不允许方法调用。

I don't think there is any workaround, apart for a large-scale change to all of the switch statements. But I wouldn't worry. Your IDE should be able help you find and replaces all occurrences of the old constants.

除了对所有 switch 语句进行大规模更改外,我认为没有任何解决方法。但我不会担心。您的 IDE 应该能够帮助您找到并替换所有出现的旧常量。

FOLLOWUP

跟进

The following code from your comment won't work either:

您评论中的以下代码也不起作用:

private int INTEGER_VALUE_HOLDER = DataType.INTEGER_VALUE.getId(); 
public static final int INTEGER_VALUE = INTEGER_VALUE_HOLDER;

Firstly, INTEGER_VALUE_HOLDERis not a "constant variable" according to the definition in JLS 4.12.4 Final Variables. Therefore neither is INTEGER_VALUE.

首先,INTEGER_VALUE_HOLDER根据JLS 4.12.4 Final Variables 中的定义,它不是“常量变量” 。因此两者都不是INTEGER_VALUE

Secondly, the initializer expression for a static cannot refer to this, and INTEGER_VALUE_HOLDERis really another way of saying this.INTEGER_VALUE_HOLDER.

其次,静态的初始化表达式不能引用thisINTEGER_VALUE_HOLDER实际上是另一种说法this.INTEGER_VALUE_HOLDER

回答by AlexR

Java has native support of enums in switch statements. In your case you should say:

Java 原生支持 switch 语句中的枚举。在你的情况下,你应该说:

DataType type = ...;

switch (type) {
    case UNKNOWN_VALUE
        //do something
        break;
    case INTEGER_VALUE
        //do something
        break;
    case LONG_VALUE
        //do something
        break;
    case STRING_VALUE
        //do something
        break;
    case BOOLEAN_VALUE
        //do something
        break;

回答by Grzegorz Oledzki

Try getting rid of the GroupConstants.prefix in your case statements. For reasons completely unclear to me, it doesn't accept the same constant if it's prefixed with class name.

尝试去掉GroupConstants.case 语句中的前缀。由于我完全不清楚的原因,如果它以类名为前缀,则它不接受相同的常量。

So instead of

所以代替

 case GroupConstants.STRING_VALUE:

please try:

请尝试:

 case STRING_VALUE:

You might need a static import to make it compile.

您可能需要静态导入以使其编译。

回答by ingyesid

in eclipse IDE is simple ,in switch sentence CTRL + 1 and convert switch sentence - if-else sentence http://tools.android.com/tips/non-constant-fields

在 Eclipse IDE 中很简单,在 switch 语句 CTRL + 1 中转换 switch 语句 - if-else 语句http://tools.android.com/tips/non-constant-fields