在Java 21上编译一个实现List的deftype将创建一个类,其中包含对(Java 21新引入的)SequencedCollection类型的引用(这引入了新的方法reverse)。在较旧的Java运行时中加载编译后的类将抛出异常,因为SequencedCollection类型不存在。
给定repro.clj
(ns repro)
(deftype C []
java.util.List)
使用Java 21 JDK编译到一个类,javap显示
public final class repro.C implements java.util.List,clojure.lang.IType {
public repro.C();
Code:
0: aload_0
1: invokespecial #13 // Method java/lang/Object."<init>":()V
4: return
public static clojure.lang.IPersistentVector getBasis();
Code:
0: invokestatic #20 // Method clojure/lang/Tuple.create:()Lclojure/lang/IPersistentVector;
3: areturn
public java.util.SequencedCollection reversed();
Code:
0: aload_0
1: invokeinterface #25, 1 // InterfaceMethod java/util/List.reversed:()Ljava/util/List;
6: areturn
public static {};
Code:
0: return
}
使用较旧的Java版本在Clojure中加载此类将抛出
user=> (require 'repro)
Execution error (ClassNotFoundException) at jdk.internal.loader.BuiltinClassLoader/loadClass (BuiltinClassLoader.java:641).
java.util.SequencedCollection
List为其父接口SequenceCollection提供了一个默认的reversed()
方法实现。不确定为什么这里会创建这样的转发方法,但是它与其他方法不同,因为我们正在转发父默认方法实现。