다음 코드가 무한 재귀 일종의 힙 (OutOfMemoryError 또는 무언가)에 해당하는 스택 오버플로를 일으키는 이유가 무엇인지 이해할 수 없습니다. 정적 초기화가 이런 식으로 경비를 제공하고 대신 NullPointerException을 throw합니까?오브젝트/정적 작성에서 무한 재귀/왜이 코드가 NullPointerException을 던지고 있습니까?
편집 : 이해가 안된다고 생각합니다. public static void main(String[] args)
은 StaticClass
에서 정적 메서드를 호출합니다. 이 메서드를 사용하기 전에 먼저 StaticClass
을로드해야합니다. doSmth()
이라고합니다. 클래스가로드되면 모든 정적 코드가 실행됩니다. StaticClass
클래스에서 objClass
은 new ObjClass()
의 값을 가진 정적 필드이므로 null
(throw NullPointerException
)이되어서는 안됩니다. 분명히 new ObjClass()
은 인스턴스화 할 수 없습니다.이 작업을 수행하려면 StaticClass
을로드해야하며 StaticClass
이로드 될 때 이미 발생합니다 (따라서 무한 재귀 또는 유추 교착 상태 비유). 문제는 JVM이 objClass
이 어떤 종류의 반복 호출 (recurrent call)을하기 때문에 new ObjClass()
을 초기화 할 수 없다는 대신 null이라는 것입니다.
정상적인 경우 호출자 때문에 NullPointerException이 발생합니다. 그러나이 경우 호출 수신자 만 변경할 수 있습니다 (끝에있는 주석이있는 행을 ObjClass
생성자에서 제거). NullPointerException
을 수신하지 않습니다. 클래스 로딩 JVM은 ObjClass
에 대한 인스턴스를 생성 (인스턴스 생성이 아직 완료되지 않음)라는 시간 ObjClass
생성자 null
에 objClass
점을 참조하려고
Exception in thread "main" java.lang.ExceptionInInitializerError
at pack.ObjClass.main(ObjClass.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.NullPointerException
at pack.ObjClass$StaticClass.doSmth(ObjClass.java:39)
at pack.ObjClass.<init>(ObjClass.java:20)
at pack.ObjClass$StaticClass.<clinit>(ObjClass.java:34)
... 6 more
그게 내가 이해하지 못하는 이유입니다. 'StaticClass'의 로딩이 끝나기 전에 어떻게'doSmth()'메소드를 평가할 수 있습니까? 그리고 클래스가 완료 될 때까지 객체를로드하는 'objClass'는 null이 아닌 객체를 가리켜 야합니다; ObjClass를 인스턴스화 할 수 없다면 예외를 던져야합니다. – m3th0dman
사실 정적 초기화 프로그램에 문제가 있었고 그 원인은'NullPointerException'입니다. – m3th0dman