我已在CLJ-1172中报告此问题,但未收到Clojure团队的任何反馈。也许有人在这里可以告诉我什么是错的。这是我的代码:
import clojure.lang.Compiler;
Compiler.load(new StringReader("(+ 5 6)"));
运行时异常:
java.lang.ExceptionInInitializerError
at clojure.lang.Compiler.<clinit>(Compiler.java:47)
Caused by: java.lang.NullPointerException
at clojure.lang.RT.baseLoader(RT.java:2043)
at clojure.lang.RT.load(RT.java:417)
at clojure.lang.RT.load(RT.java:411)
at clojure.lang.RT.doInit(RT.java:447)
at clojure.lang.RT.<clinit>(RT.java:329)
看起来RT
和Compiler
类静态地相互引用。我正在使用org.clojure:clojure:1.5.0
依赖。
答案 0 :(得分:8)
只要字段按正确的顺序初始化,类就可以静态引用彼此。在这种情况下,Clojure可能希望在RT
之前初始化Compiler
。这是事件的顺序:
Compiler
进行静态调用时,Java会初始化该类中的所有静态字段。 Compiler.FNONCE
的静态初始化程序(第47行)调用RT
中的静态方法,这会导致在计算和设置FNONCE
的值之前初始化整个类。 / LI>
RT
的静态初始化程序块调用静态方法,该方法最终引用静态Compiler.LOADER
字段。Compiler
类,但它会看到Compiler
当前正在初始化并且只是获取当前值。字段按照在文件中声明的顺序进行初始化,并且LOADER
后FNONCE
返回null
的未初始化值,在{{{}}中取消引用时抛出NPE 1}}。底线:在致电RT
之前,在RT
(或读取静态字段)中调用某个静态方法,您的错误就会消失。
有关类初始化细节的更多详细信息,请参见Java Language Specification的第12.4节。