2024 Clojure 状况调查! 分享您的想法。

欢迎!请参阅 关于 页面了解有关如何使用此页面的更多信息。

0
Clojure

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

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

考虑以下代码

`
(import 'javafx.scene.control.Cell)

(defn f [] Cell)
`

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

方法
将 {{ObjExpr.emitValue}} 修改为在发出的值为 Class 时发出对 {{RT.classForNameNonLoading}} 而非 {{RT.classForName}} 的调用来替换。

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

现有技术
之前的 {{import}} 形式已更改为以类似方式不加载类(链接: 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
by
参考: https://clojure.atlassian.net/browse/CLJ-2250(由ragge报告)
...