В 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;
...
}
Можно ли перебрать все константы, объявленные в этом интерфейсе?
6 ответов
Используя отражение:
Field[] interfaceFields=HttpConstants.class.getFields();
for(Field f:interfaceFields) {
//do something
}
Но в любом случае, если вы сможете изменить дизайн своего класса, я бы порекомендовал вам заняться созданием статических перечислимых констант. Таким образом, добавление вашего класса всегда будет содержать значение 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 field : interfaceFields) {
int constant = field.getInt(null);
//Do something with the field
}
Однако этот подход лучше использовать с перечислениями, поскольку ошибки кодирования с отражением приводят к исключениям времени выполнения вместо ошибок времени компиляции.
for(Field f : HttpConstants.class.getFields()){
int constant = f.getInt(null);
}
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()
,
Ну, обычно, когда у меня есть что-то подобное, я делаю Map в интерфейсе, который имеет ключи - имена констант со значениями константы - значения.
И вот как я могу перебирать их.
Я хотел бы знать, что вы думаете об этой практике
Рассмотрите возможность использования 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);
}
}