2012-03-14 18 views
9

en una interfaz, almaceno las constantes de esta manera (me gustaría saber qué piensa de esta práctica). Este es solo un ejemplo falso.En Java, ¿cómo iterar en las constantes de una interfaz?

interface HttpConstants { 
    /** 2XX: generally "OK" */ 
    public static final int HTTP_OK = 200; 
    public static final int HTTP_CREATED = 201; 
    public static final int HTTP_ACCEPTED = 202; 
    public static final int HTTP_NOT_AUTHORITATIVE = 203; 
    public static final int HTTP_NO_CONTENT = 204; 
    public static final int HTTP_RESET = 205; 
    public static final int HTTP_PARTIAL = 206; 

     ... 
} 

¿Hay alguna manera de iterar sobre todas las constantes declaradas en esta interfaz?

+0

Opinión: enums _do_ ofrece muchos beneficios en el código moderno, muy recomendable. PERO no en todos los casos. Las cadenas se utilizan mucho análogas a "identificador" (por ejemplo, nombres de atributos, claves de propiedades, identificadores de vista JSF, nombres de consultas nombrados por JPA y marcadores de posición de consulta, roles de seguridad, ...). Problema: los literales de cadena son muy fáciles de escribir y no tienen comprobación de tiempo de compilación. Prefiero declarar todas esas cadenas como constantes, generalmente en una enumeración. SIN EMBARGO, al usarlos como ** parámetros de anotación **, las enumeraciones no están permitidas y todavía hay que recurrir a 'cadena final estática pública 'similar a su código. – fr13d

Respuesta

18

El uso de la reflexión:

Field[] interfaceFields=HttpConstants.class.getFields(); 
for(Field f:interfaceFields) { 
    //do something 
} 

Pero de todos modos, si se puede rediseñar su clase, se lo recomiendo que para manejar una construcción constantes de enumeración estática. Así, suposing su clase contendrá siempre un valor int para cada constante:

enum HttpConstants { 

    HTTP_OK(200), HTTP_CREATED(201), HTTP_ACCEPTED(202), 
    HTTP_NOT_AUTHORITATIVE(203),HTTP_NO_CONTENT(204), 
    HTTP_RESET(205), HTTP_PARTIAL(206) /* ... */; 

    private int value; 

    HttpConstants(int aValue) { 
     value=aValue; 
    } 

    public int getValue() { 
     return value; 
    } 
} 

A continuación, recorrer el array:

for(HttpConstants val: HttpConstants.values()) { 
     int value=val.getValue(); 
      //... 
    } 

Por lo tanto, evitando el acceso a la API de reflexión.

2

Bueno, generalmente cuando tengo algo así hago un Mapa en la interfaz que tiene las claves - nombres constantes con valores constantes - valores.

Y así es como puedo iterar sobre ellos.

4
for(Field f : HttpConstants.class.getFields()){ 
     int constant = f.getInt(null); 
} 
+2

por cierto esas constantes se definen en java.net.HttpURLConnection –

6

Crearía estas constantes como una enumeración. Los enums en Java pueden tener sus propios campos y métodos, lo cual es muy conveniente para su caso. Así que me gustaría hacer esto de la siguiente manera:

enum HttpConstant { 
    HTTP_OK(200), 
    HTTP_CREATED(201), 
    HTTP_ACCEPTED(202), 
    HTTP_NOT_AUTHORITATIVE(203), 
    HTTP_NO_CONTENT(204), 
    HTTP_RESET(205), 
    HTTP_PARTIAL(206); 

    private final int id; 

    HttpConstant(int id) { 
     this.id = id; 
    } 

    int getId() { 
     return id; 
    } 
} 

Ahora la iteración es fácil:

for (HttpConstant constant : HttpConstant.values()) { 
    //Do something with the constant 
} 

De esta manera también es fácil de añadir asociar algunos valores nuevos con las constantes, sólo hay que añadir nuevos campos

En este momento usted puede utilizar la reflexión:

Field[] interfaceFields = HttpConstants.class.getFields(); 
for (Field field : interfaceFields) { 
    int constant = field.getInt(null); 
    //Do something with the field 
} 

Sin embargo, es mejor usar el enfoque con enumeraciones, ya que con los errores de codificación de reflexión dar lugar a excepciones de tiempo de ejecución en lugar de errores en tiempo de compilación.

3
public enum HttpConstant { 
    /** 2XX: generally "OK" */ 
    HTTP_OK(200). 
    HTTP_CREATED(201), 
    HTTP_ACCEPTED(202), 
    HTTP_NOT_AUTHORITATIVE(203), 
    HTTP_NO_CONTENT(204), 
    HTTP_RESET(205), 
    HTTP_PARTIAL(206); 

    private int code; 
    private HttpConstant(int code) { 
     this.code = code; 
    } 

    public int getCode() { 
     return code; 
    } 
} 

con HttpConstant.values().

1

Me gustaría saber lo que piensa de esta práctica

Considere el uso de un enum en lugar de una interfaz con constantes.

enum HttpResultCode { 
    HTTP_OK(200), 
    HTTP_CREATED(201), 
    HTTP_ACCEPTED(202), 
    HTTP_NOT_AUTHORITATIVE(203), 
    HTTP_NO_CONTENT(204), 
    HTTP_RESET(205), 
    HTTP_PARTIAL(206); 

    private final int code; 

    private HttpResultCode(int code) { 
     this.code = code; 
    } 

    public int getCode(int code) { 
     return code; 
    } 

    public static HttpResultCode forCode(int code) { 
     for (HttpResultCode e : HttpResultCode.values()) { 
      if (e.code == code) { 
       return e; 
      } 
     } 

     throw new IllegalArgumentException("Invalid code: " + code); 
    } 
} 
Cuestiones relacionadas