В 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);
    }
}
Другие вопросы по тегам