【发布时间】:2020-07-24 06:13:32
【问题描述】:
在org.springframework.core.SerializableTypeWrapper(版本5.2.3)中,第112行有如下代码:
if (GraalDetector.inImageCode() || !Serializable.class.isAssignableFrom(Class.class)) {
// Let's skip any wrapping attempts if types are generally not serializable in
// the current runtime environment (even java.lang.Class itself, e.g. on Graal)
return providedType;
}
我对第二次检查 (!Serializable.class.isAssignableFrom(Class.class)) 感到好奇:它是否可以评估为 true(也就是说,Serialazable.class 不能从 Class.class 分配)?
Class#isAssignableFrom()javadoc 是这样说的:
确定此 Class 对象表示的类或接口是否与指定的 Class 参数表示的类或接口相同,或者是其超类或超接口。
查看Class的代码,看到如下:
public final class Class<T> implements java.io.Serializable
所以Serializable 是Class 的超接口并且应该总是 可以从Class 分配。但 Spring 代码中的检查表明有时不是。
怎么会?在什么情况下会发生这种情况?为什么它们不违反 Java 语言规范?
【问题讨论】:
-
if块内的代码注释看起来很相关:“如果类型在当前运行时环境中通常不可序列化(甚至 java.lang.Class 本身,例如在 Graal 上)”。我认为“Graal”是指GraalVM,在创建本机图像时有limitations。我猜在 GraalVM 上可能是Class不 实现Serializable?他们用它来测试当前环境是否是 Graal。但我不确定。 -
@Slaw 我已经编译了一个带有以下行的测试程序
System.out.println("Is assignable: " + java.io.Serializable.class.isAssignableFrom(Class.class));;它在使用java(OpenJDK 和 GraalVM 版本)运行时或当我使用 GraalVM 的native-image工具从该程序构建本机映像时都会输出true。所以(至少在当前版本的 Graal 中),这在原生图像中似乎是不可能的(除非有一些特殊条件......)。
标签: java spring graalvm graalvm-native-image