Почему перечисление java не создается до тех пор, пока не будет вызван обратный вызов класса?

У меня есть класс Android, который имеет обратный вызов от асинхронного процесса HTTP и перечисление с несколькими кодами состояния в:

public abstract class HttpPackage {

    public enum StatusCode {
        SUCCESS(0),
        NOT_FOUND(100),
        USERNAME_NOT_FOUND(101),
        AUTH_FAILED(110),
        SAVE_ERROR(111)
        //etc.

        private final int mCode;

        StatusCode(int i) {
            mCode = i;
            sByCode.put(i, this);
        }

    }

    private static final HashMap<Integer, StatusCode> sByCode = new HashMap<Integer, StatusCode>();

    //...
}

Я обнаружил, что обратный вызов в классе HttpPackage выполняется до того, как enum конструкции, что означает, что когда я пытаюсь извлечь код состояния из статической карты кодов, он возвращает ноль, и мой код думает, что все каналы не работают (когда это не так). С чего бы это enum конструировать после того, как обратный вызов ударил?

1 ответ

Решение

Классы загружаются лениво в Java. Если вы получите доступ к карте до загрузки класса StatusCode, тогда, конечно, она будет пустой.

Карта должна быть в самом перечислении. Таким образом, если вы обращаетесь к карте, вы гарантируете, что класс enum был загружен, и что карта не пуста. Карта также должна быть скрыта от внешнего кода. Вы должны предоставить статический StatusCode getByCode(int code) метод в перечислении.

РЕДАКТИРОВАТЬ: пример кода:

public enum StatusCode {
    SUCCESS(0),
    NOT_FOUND(100),
    USERNAME_NOT_FOUND(101),
    AUTH_FAILED(110),
    SAVE_ERROR(111);

    private final int code;

    private static final Map<Integer, StatusCode> map = new HashMap<Integer, StatusCode>();

    static {
        for (StatusCode sc : values()) {
            map.put(sc.getCode(), sc);
        }
    }

    StatusCode(int i) {
        this.code = i;
    }

    public static StatusCode getByCode(int code) {
        return map.get(code);
    }

    public int getCode() {
        return code;
    }

    public static void main(String[] args) {
        System.out.println(StatusCode.getByCode(111));
    }
}

Или вы могли бы также использовать getMap() статический метод внутри конструктора, который лениво инициализирует карту, если она пуста.

Другие вопросы по тегам