2012-03-14 11 views
9

in un'interfaccia, memorizzo le costanti in questo modo (mi piacerebbe sapere cosa ne pensi di questa pratica). Questo è solo un esempio fittizio.In Java, come eseguire un'iterazione sulle costanti di un'interfaccia?

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; 

     ... 
} 

C'è un modo per iterare su tutte le costanti dichiarate in questa interfaccia?

+0

Pareri: le enumerazioni _do_ offrono molti vantaggi nel codice moderno, altamente raccomandato. MA non in tutti i casi. Le stringhe vengono utilizzate molto analogamente all '"identificatore" (ad esempio nomi di attributi, chiavi di proprietà, ID vista JSF, nomi di query con nome JPA e segnaposto di query, ruoli di sicurezza, ...). Problema: i valori letterali stringa sono _molto_ facili da digitare e non hanno il controllo del tempo di compilazione. Preferisco dichiarare tutte queste stringhe come costanti, di solito in un enum. TUTTAVIA, quando li si utilizza come ** parametri di annotazione **, le enumerazioni non sono consentite e si deve ancora ripiegare su 'stringa finale statica pubblica simile al codice. – fr13d

risposta

18

Utilizzando riflessione:

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

Ma comunque, se è possibile riprogettare la classe, mi vuoi consigliare di gestire una statica costruzione costanti enum. Quindi, suposing la classe conterrà sempre un valore int per ogni costante:

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; 
    } 
} 

Poi, ad anello su di esso:

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

Così, evitando l'accesso alle API di riflessione.

2

Di solito quando ho qualcosa di simile, faccio una mappa nell'interfaccia che ha le chiavi - nomi costanti con valori costanti - valori.

Ed è così che posso scorrere su di loro.

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

btw quelle costanti sono definite in java.net.HttpURLConnection –

6

Vorrei creare queste costanti come un'enumerazione. Enums in Java può avere i propri campi e metodi, che sono molto convenienti per il tuo caso. Quindi mi sento di fare questo nel modo seguente:

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; 
    } 
} 

Ora l'iterazione è facile:

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

In questo modo è anche facile aggiungere associare alcuni nuovi valori con le costanti, basta aggiungere nuovi campi.

In questo momento si può utilizzare la riflessione:

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

Tuttavia, è meglio usare l'approccio con le enumerazioni perché con la riflessione errori di codifica comportare eccezioni di runtime invece di errori di compilazione.

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

Mi piacerebbe sapere cosa ne pensi di questa pratica

Considerare l'utilizzo di un enum invece di un'interfaccia con costanti.

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); 
    } 
}