Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

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

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

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.

[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?

like image 938
emeraldjava Avatar asked Nov 25 '10 13:11

emeraldjava


People also ask

How do you solve a constant error required in java?

Sometimes the switch variable can also make that error for example: switch(view. getTag()) {//which is an Object type case 0://will give compiler error that says Constant expression required //... } To solve you should cast the variable to int(in this case).

Can you use a switch statement around an enum in java?

We can use also use Enum keyword with Switch statement. We can use Enum in Switch case statement in Java like int primitive.

How do you define a constant expression in java?

A constant expression is an expression that yields a primitive type or a String, and whose value can be evaluated at compile time to a literal. The expression must evaluate without throwing an exception, and it must be composed of only the following: Primitive and String literals.

Can a switch statement evaluate an enum?

With the switch statement you can use int, char or, enum types. Usage of any other types generates a compile time error.


3 Answers

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

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;
like image 54
AlexR Avatar answered Oct 17 '22 09:10

AlexR


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 Expressions for the gory details, and you will see that method calls are not allowed in constant expressions.

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.

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_HOLDER is not a "constant variable" according to the definition in JLS 4.12.4 Final Variables. Therefore neither is INTEGER_VALUE.

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

like image 33
Stephen C Avatar answered Oct 17 '22 11:10

Stephen C


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.

So instead of

 case GroupConstants.STRING_VALUE:

please try:

 case STRING_VALUE:

You might need a static import to make it compile.

like image 9
Grzegorz Oledzki Avatar answered Oct 17 '22 11:10

Grzegorz Oledzki