Question

I have an Android class which has a callback from an asynchronous HTTP process, and an enum with a number of status codes in:

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

    //...
}

I've discovered the callback in the HttpPackage class is being hit before the enum constructs, which means that when I try to extract a status code from the static code map, it returns null, and my code thinks all the feeds are failing (when they aren't). Why would this enum be constructing after the callback is hit?

Was it helpful?

Solution

Classes are loaded lazily in Java. If you access the map before the StatusCode class is loaded, then of course it will be empty.

The map should be in the enum itself. This way, if you're accessing the map, you're guaranteed that the enum class has been loaded, and that the map is not empty. The map should also be hidden from the outside code. You should provide a static StatusCode getByCode(int code) method in the enum.

EDIT: example 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));
    }
}

Or you could also use a getMap() static method inside the constructor which lazily initializes the map if it's null.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top