Ответ на такие вопросы обычно находится где-то в спецификации ... (§12.4.2)
Что происходит при инициализации классов:
Шаги 1-4 несколько не связаны с этим вопросом. Шаг 5 вот что вызывает исключение:
5
. Если объект Class находится в ошибочном состоянии, , тогда инициализация невозможна. Освободите блокировку объекта Class и сгенерируйте NoClassDefFoundError.
6-8 продолжить инициализацию, 8 выполняет инициализаторы, и то, что обычно происходит, находится на шаге 9:
9
. Если выполнение инициализаторов завершается нормально, затем заблокируйте этот объект Class, пометьте его как полностью инициализированный, уведомите все ожидающие потоки, снимите блокировку и завершите эту процедуру в обычном режиме.
Но мы получили ошибку в инициализаторе так:
10
. В противном случае инициализаторы должны были завершиться внезапно, выдав некоторое исключение E. Если класс E не является Error или одним из его подклассов, тогда создаст новый экземпляр класса ExceptionInInitializerError, с E как аргумент и используйте этот объект вместо E на следующем шаге. Но если новый экземпляр ExceptionInInitializerError не может быть создан из-за возникновения OutOfMemoryError, вместо этого используйте объект OutOfMemoryError вместо E на следующем шаге.
Да, мы видим ExceptionInInitializerError
b / c исключения нулевого указателя.
11
. Заблокируйте объект Class, отметьте его как ошибочный, уведомите все ожидающие потоки, снимите блокировку и завершите эту процедуру внезапно по причине E или ее замене, как определено в предыдущем шаге. (Из-за недостатка в некоторых ранних реализациях исключение во время инициализации класса игнорировалось, а не вызывало ExceptionInInitializerError, как описано здесь.)
И тогда класс помечается как ошибочный, поэтому мы получаем исключение из шага 5 во второй раз.
Удивительной частью является третья распечатка, которая показывает, что TestClass.class
в MainClass
фактически содержит ссылку на физический Class
объект.
Возможно, потому что TestClass
все еще существует, он просто помечен как ошибочный. Он уже загружен и проверен.