2010-11-25 15 views
6

tengo una clase declarar constantes para mi aplicaciónEnum de Java: ¿Reformular las sentencias del conmutador 'requiere expresión constante' error de compilación?

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

En el código no es un conjunto de instrucciones 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: 
.. 
} 

Quiero refactorizar los valores constantes int a ser representado por una enumeración

public enum DataType { 

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

por lo que mi código podría tener este aspecto

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

y las horas extraordinarias puedo cambiar las instrucciones de mi interruptor. Cuando cambio la referencia int final estática para apuntar a la enumeración, todas mis sentencias switch se rompen.

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

No quiero ser forzado a cambiar todos los interruptores todavía, ¿entonces hay un trabajo limpio?

+0

no es su GroupConstants a la antigua? ¿No debería ser el caso de DataType.INTEGER_VALUE: debería estar en el error del compilador? –

+0

Basado en lo que has mostrado hasta ahora, no puedo ver cuál es el problema; esto debería funcionar en función de lo que supongo * que está haciendo en, por ejemplo, 'ParameterComponent'. Pero, de nuevo, los mensajes de error no tienen nada que ver con la nueva clase 'DataType', así que tal vez estoy transfiriendo erróneamente el código que está causando los errores de compilación. ¿Podría pegar un poco del código que no compila (por ejemplo, la clase ParameterComponent) y resaltar dónde se produce el error? –

Respuesta

5

Eso no funcionará. El problema es que la llamada getId() significa que la expresión de valor de la constante no es una expresión constante en tiempo de compilación según JLS. Consulte JLS 15.28 Constant Expressions para ver los detalles sangrientos, y verá que las llamadas a métodos no están permitidas en expresiones constantes.

No creo que haya ninguna solución alternativa, aparte de un cambio a gran escala de todas las instrucciones de cambio. Pero no me preocuparía. Su IDE debería poder ayudarlo a encontrar y reemplazar todas las apariciones de las constantes antiguas.

FOLLOWUP

El siguiente código de su comentario no funciona bien:

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

En primer lugar, INTEGER_VALUE_HOLDER no es una "variable constante", según la definición de JLS 4.12.4 Final Variables. Por lo tanto, tampoco es INTEGER_VALUE.

En segundo lugar, la expresión del inicializador de una estática no puede hacer referencia a this, y INTEGER_VALUE_HOLDER es realmente otra forma de decir this.INTEGER_VALUE_HOLDER.

+0

Su correcto: un trabajo desagradable es: private int INTEGER_VALUE_HOLDER = DataType.INTEGER_VALUE.getId(); public static final int INTEGER_VALUE = INTEGER_VALUE_HOLDER; Pero eso frustra el propósito del refactor. – emeraldjava

8

Java tiene soporte nativo de enumeraciones en instrucciones de conmutación. En el caso de que digas:

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; 
+0

Su correcta acerca del uso de Enum para controlar la declaración de cambio. En mi caso, el DataType representa un tipo de objeto, por lo que en lugar de refactorizar el conmutador para usar Enum, planeo crear una interfaz y mover la lógica en las sentencias case al objeto, lo que permite eliminar las instrucciones de conmutación del código. – emeraldjava

2

intentar conseguir librarse de la GroupConstants. prefijo en sus estados de cuenta de casos. Por razones completamente desconocidas para mí, no acepta la misma constante si está prefijada con el nombre de la clase.

Así que en lugar de

case GroupConstants.STRING_VALUE: 

Por favor intente:

case STRING_VALUE: 

Es posible que tenga una importación estática para que se compile.

+1

¿por qué un voto a favor? –

Cuestiones relacionadas