Ленивое создание констант с помощью фабричного метода вызывает ошибку при использовании в конструкторе - PullRequest
0 голосов
/ 26 февраля 2012

Когда конструктор использует ссылку на константу, для которой создается ленивый экземпляр, java генерирует ExceptionInInitializerError (в частности, в строке «this (ClassA.INSTANCE1)»).

public class ClassA {
    public static final ClassA INSTANCE1 = get("INSTANCE1");
    public static final ClassA INSTANCE2 = get("INSTANCE2");

    private static final Map<String, ClassA> MULTITON_MAP = new HashMap<String, ClassA>();

    private String name;

    private ClassA(String name) {
        this.name = name;
    }

    public static ClassA get(String name) {
        ClassA toReturn = MULTITON_MAP.get(name);
        if (toReturn == null) {
            toReturn = new ClassA(name);
            MULTITON_MAP.put(name, toReturn);
        }
        return toReturn;
    }
}

public class ClassB {
    private ClassA type;

    public ClassB() {
        this(ClassA.INSTANCE1);
    }

    public ClassB(ClassA type) {
        this.type = type;
    }

    public static void main(String[] args) {
        new ClassB();
    }
 }

Я решил проблему, удалив ленивые экземпляры и переместив их в статический блок.

public class ClassA {
    public static final ClassA INSTANCE1;
    public static final ClassB INSTANCE2;

    ...

    static {
        INSTANCE1 = new ClassA("INSTANCE1");
        INSTANCE2 = new ClassA("INSTANCE2");

        MULTITON_MAP.put("INSTANCE1", INSTANCE1);
        MULTITON_MAP.put("INSTANCE2", INSTANCE2);
    }

    ...
}

Итак, мой вопрос: почему Java не может справиться с тем, что я делал ранее? Что вызывает ошибку и почему?

Спасибо большое!

Ответы [ 2 ]

1 голос
/ 26 февраля 2012
private static final Map<String, ClassA> MULTITON_MAP = new HashMap<String, ClassA>();  
public static final ClassA INSTANCE1 = get("INSTANCE1");
public static final ClassA INSTANCE2 = get("INSTANCE2");

Вы пытались инициализировать экземпляры до инициализации карты.

1 голос
/ 26 февраля 2012

Я думаю, что ваша проблема в том, что вы пытаетесь инициализировать INSTANCE1 до MULTITON_MAP, но создание экземпляра INSTANCE1 зависит от MULTITON_MAP.

например. когда вы звоните MULTITON_MAP.get(name); в get, MULTITON_MAP по-прежнему равен нулю.

...