在Java中,如何迭代接口的常量?

在Java中,如何迭代接口的常量?,java,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

在接口中,我以这种方式存储常量(我想知道您对这种做法的看法)。这只是一个虚构的例子

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;

        ...
}

有没有一种方法可以迭代这个接口中声明的所有常量

通常当我有类似的东西时,我会在界面中创建一个映射,其中包含键-常量名称和常量值-值

这就是我可以迭代它们的方式。

使用反射:

for(Field f : HttpConstants.class.getFields()){
       int constant = f.getInt(null);
}
Field[] interfaceFields=HttpConstants.class.getFields();
for(Field f:interfaceFields) {
   //do something
}
Field[] interfaceFields = HttpConstants.class.getFields();
for (Field field : interfaceFields) {
    int constant = field.getInt(null);
    //Do something with the field
}
但无论如何,如果您可以重新设计类,我建议您处理静态枚举常量构造。因此,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。

我将创建这些常量作为枚举。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 f:interfaceFields) {
   //do something
}
Field[] interfaceFields = HttpConstants.class.getFields();
for (Field field : interfaceFields) {
    int constant = field.getInt(null);
    //Do something with the field
}
但是,最好对枚举使用这种方法,因为反射编码错误会导致运行时异常,而不是编译时错误

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()

我想知道你对这种做法的看法

考虑使用
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);
    }
}

顺便说一句,这些常量是在java.net.httpurlconnectionovine中定义的:强烈建议使用枚举在现代代码中提供很多好处。但并非所有情况下都如此。字符串在很大程度上类似于“标识符”(例如属性名称、属性键、JSF视图ID、JPA命名查询名称和查询占位符、安全角色等)。问题:字符串文字很容易输入错误,并且没有编译时检查。我更喜欢将所有此类字符串声明为常量,通常在枚举中。但是,当使用它们作为注释参数时,不允许使用枚举,并且仍然必须使用与代码类似的
public static final String
s。