Может ли объект, ссылающийся на себя внутри двойной инициализации, не дать NPE?
У меня есть этот маленький кусочек кода, который всегда выдает NPE:
public class Test1 {
private final static Object OBJECT = new Object() {{
System.out.println("OBJECT.toString() = " + OBJECT.toString());
}};
public static void main(String[] args) { }
}
Есть ли способы, хотя это OBJECT
можно инициализировать в блоке инициализации экземпляра? Или будет любая возможная ссылка на OBJECT
в блоке инициализации экземпляра всегда бросать NPE?
Для тех, кто быстрее всех стреляет, прочитайте это: Нет, я не прошу вас исправить мою ошибку. Это упрощенный фрагмент кода, который я где-то видел и который, к моему удивлению, не дает нулевого предупреждения ни в Eclipse, ни в Netbeans, что я ожидаю.
1 ответ
Инициализация с двойной скобкой - это просто анонимный внутренний класс с инициализатором экземпляра. Поэтому применяются правила, регулирующие создание объектов.
NPE - это исключение времени выполнения, поэтому в среде IDE для выявления виновных используется эвристика, а не строгость и достоверность, обеспечиваемые статической типизацией, объявленными исключениями и статическим анализом кода. Здесь он должен выполнить код, чтобы найти проблемы во время выполнения.
Происходит следующее: статический член инициализируется путем присвоения ему анонимного внутреннего класса. Конструктор внутреннего класса завершен, так как это правило для инициализаторов экземпляра. Однако ссылка присваивается только после завершения инициализаторов, чего у них нет к тому времени, когда вы пытаетесь разыменовать OBJECT
,
Похоже, очень круговое объяснение, но это потому, что происходит круговая ссылка;)