2012-03-14 47 views
9

在一个接口中,我以这种方式存储常量(我想知道你对这种做法的看法)。这只是一个虚拟的例子。在Java中,如何迭代接口的常量?

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; 

     ... 
} 

有没有一种方法可以迭代在此接口中声明的所有常量?

+0

意见:enums _do_在现代代码中提供了很多好处,强烈推荐。但不是所有情况。字符串与“标识符”(例如,属性名称,属性键,JSF视图ID,JPA命名的查询名称和查询占位符,安全角色...)有很多相似之处。问题:字符串文字很容易输入错误,并且没有编译时间检查。我更喜欢将所有这样的字符串声明为常量,通常在枚举中。但是,将它们用作**注释参数**时,不允许使用枚举,并且仍然需要回退到类似于您的代码的'public static final String's。 – fr13d 2014-06-25 15:32:29

回答

18

使用反射:

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

但无论如何,如果你可以重新设计你的课,我会建议你处理一个静态的枚举常量建设。所以,suposing类将始终包含在每一恒定int值:

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

然后,循环就可以了:

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

因此,避免了进入反射API。

2

那么通常当我有类似的东西,我在接口有一个地图的键 - 常数名称值常量 - 值。

这就是我可以迭代他们。

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

btw这些常量是在java.net.HttpURLConnection – 2012-03-14 10:48:38

6

我会创建这些常量作为枚举。 Java中的枚举可以有自己的字段和方法,这对你的情况非常方便。所以,我会做这样的方式如下:

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

现在迭代很简单:

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

这样,它也很容易添加一些新的值与常量关联,你只需要添加新领域。

现在你可以使用反射:

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

然而,最好是使用带有因为反射编码错误枚举的方法导致运行时异常,而不是编译时错误。

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

HttpConstant.values()

1

我想知道你使用enum不是用常量的接口都认为这种做法

考虑的。

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