Насколько я понимаю, @ ответ Евгения абсолютно правильный. Я решил добавить объяснение простыми словами. Надеюсь, это кому-нибудь поможет.
Ответ: Вызовы Object.getClass
использовались компилятором в JDK8 для генерации исключений NullPointerException, где это необходимо. В вашем примере эта проверка не нужна, так как new Outer()
не может быть нулем, но компилятор не был достаточно умен, чтобы определить это.
В более поздних версиях JDK нулевые проверки были изменены, чтобы использовать более читаемый Objects.requireNotNull
. Компилятор также был улучшен для оптимизации ненужных проверок нуля.
Пояснение:
Рассмотрим код, подобный следующему:
class Outer{
class Inner{
}
public static void main(String args[]){
Outer.Inner obj = ((Outer) null).new Inner();
}
}
Этот код генерирует исключение NullPointerException, как и должно быть.
Проблема в том, что NPE логичен только с точки зрения Java. Конструкторы не существуют на уровне байтового кода. Компилятор генерирует байт-код, более или менее эквивалентный следующему псевдокоду:
class Outer {
public static void main(String[] args) {
Outer tmp = (Outer) null;
Outer.Inner obj = new; //object created
tmp."<init>"(tmp);
}
}
class Outer$Inner {
//generated field
private final Outer outer;
//generated initializer
void "<init>"(Outer outer) {
this.outer = outer;
}
}
Как видите, конструктор был заменен методом. И метод сам по себе не будет проверять свой аргумент на null и, следовательно, не будет генерировать исключение.
По этой причине компилятор должен добавить дополнительную нулевую проверку для генерации NullPointerException
. До Java 8 быстрым и грязным способом для достижения этой цели было отправлять вызов на getClass
:
Outer tmp = (Outer) null;
tmp.getClass(); //generates an NPE
Как вы можете проверить, что это, действительно, причина:
- Скомпилируйте класс
Outer
выше, используя JDK 8.
- Запустите его, он должен бросить NPE.
- Удалите вызов на
Object.getClass
из Outer.class
с помощью любого редактора байт-кода (например, JBE ).
- Запустите программу еще раз, она должна успешно завершиться.