java - Serializable.class 怎么不能从 Class.class 分配?

标签 java spring graalvm graalvm-native-image

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 说:

Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter.


查看 Class 的代码,我看到以下内容:
public final class Class<T> implements java.io.Serializable
所以SerializableClass 的超接口(interface)并且应该始终可以从 Class 分配.但 Spring 代码中的检查表明有时并非如此。
怎么会?在什么情况下会发生这种情况,为什么它们不违反 Java 语言规范?

最佳答案

一个定制class loader是表达式返回 false 的一种可能(如果不太可能)机制.自定义类加载器可以做一些疯狂的事情,包括加载他们自己版本的标准 Java 类。关于类加载器的一些知识:

  • 自定义类加载器可以配置为加载任何类,甚至包括 Java 标准库类(当然不鼓励,但仍有可能)
  • 自定义类加载器通常会配置为将不知道如何加载的类委托(delegate)给系统类加载器。
  • 当 A 类引用 B 类时,将使用用于加载 A 类的任何类加载器解析该引用
  • 可以配置多个类加载器来处理同一个类,这可能会导致一个类的多个版本被加载到 JVM 中,您获得的实际实现取决于您询问的类加载器

  • 假设有一个自定义类加载器,无论出于何种原因,它被配置为加载 java.io.Serializable本身,但委托(delegate)给系统类加载器来加载其他类,包括 java.lang.Class .
    现在假设这个自定义类加载器用于加载 SerializableTypeWrapper .这意味着它也将用于解析对 java.io.Serializable 的引用。在 SerializableTypeWrapper .引用 java.lang.Class ,自定义类加载器会将其委托(delegate)给系统类加载器。系统类加载器将用于加载 java.lang.Class , 但它也将用于加载对 java.io.Serializable 的引用来自java.lang.Class .
    所以现在我们可以问这个问题 - 是 java.io.Serializable [custom]可从 java.lang.Class [standard] 分配?答案是否定的 - java.lang.Class确实实现了java.io.Serializable [standard] ,但它没有实现 java.io.Serializable [custom] .

    关于java - Serializable.class 怎么不能从 Class.class 分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63067863/

    相关文章:

    spring - CSS + Thymeleaf - CSS 未反射(reflect)在页面上

    java - 如何从拦截器在 Spring 3.1 MVC Controller 上设置对象?

    JavaBeanExecutable HV000254 缺少 Java 枚举的参数元数据

    java - Spring Boot 原生配置

    java - 如何限制tomcat-8上运行的JSP页面的客户端连接数?

    JavaMail 处理传入消息的读取回执

    java - DTO 的更好方法?

    graalvm - 捆绑 Graal VM 和其他 VM + Graal JIT 之间的区别

    java - 我可以覆盖 Android 上的自动超时吗?

    java - Android Studio : Editing a . txt 文件在内部存储中与 EditText