繁体   English   中英

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

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

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

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

代码中有一组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:
..
}

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

public enum DataType {

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

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

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

加班我可以更改我的 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:

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

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;

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

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

跟进

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

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

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

其次,对于静态初始化表达式不能引用this ,和INTEGER_VALUE_HOLDER真的是另一种说法this.INTEGER_VALUE_HOLDER

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

所以代替

 case GroupConstants.STRING_VALUE:

请尝试:

 case STRING_VALUE:

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

补充 AlexR 的答案,将字符串转换为枚举:

DataType type = Datatype.valueOf(enumName);

switch (type) {
case UNKNOWN_VALUE
    //do something
    break;

...

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM