请在2024年Clojure调查中分享您的想法!

欢迎!请查看关于页面以了解有关此内容的更多信息。

0
Clojure

问题:
当将导入的类用作值时,生成的字节码使用{{RT.classForName}}获取Class对象,导致类被加载并执行静态初始化器。这与Java调用静态初始化器时的行为不同(链接:http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1 文本:Java调用静态初始化器),这使得使用依赖于Java语义的代码来使用Clojure变得更加困难。

动机
有些代码具有只能在特定环境中执行的静态初始化器。一个典型的例子是JavaFX,其中许多JavaFX类需要在任何静态初始化器运行之前启动JavaFX平台。

考虑以下代码

`
(导入'javafx.scene.control.Cell)

(defn f [] Cell)
`

它目前无法编译和执行(例如,使用"{{clj example.clj}}"和clojure-1.9.0beta2)会失败,并抛出{{CompilerException java.lang.ExceptionInInitializerError}}异常,根本原因是"工具包未初始化"。将{{Cell}}用作函数{{f}}的返回值会导致类被加载和初始化。

方法
当要发出的值是Class时,修改ObjExpr.emitValue以调用{{RT.classForNameNonLoading}}而不是{{RT.classForName}}。

补丁
https://dev.clojure.org/jira/secure/attachment/17426/CLJ-2250-avoid-initializing-class-when-used-as-value.patch

现有技术
{{导入}}形式以前已更改为类似地不加载类(链接:https://dev.clojure.org/jira/browse/CLJ-1315 文本:CLJ-1315)和(链接:https://dev.clojure.org/jira/browse/CLJ-1743 文本:CLJ-1743)试图解决Clojure与Java语义不同的问题。

2 答案

0

评论者:ragge

添加补丁。

0
参考: https://clojure.atlassian.net/browse/CLJ-2250(由ragge报告)
...