ClassLoader.resolveClass() 实际上做了什么吗?

Sim*_*ane 2 java classloader

这是OpenJDK 20+10java.lang.ClassLoader.resolveClass(Class)中的定义:

    protected final void resolveClass(Class<?> c) {
        if (c == null) {
            throw new NullPointerException();
        }
    }
Run Code Online (Sandbox Code Playgroud)

除了检查参数是否非空之外,它似乎什么也没做。然而,文档评论声称:

    /**
     * Links the specified class.  This (misleadingly named) method may be
     * used by a class loader to link a class.  If the class {@code c} has
     * already been linked, then this method simply returns. Otherwise, the
     * class is linked as described in the "Execution" chapter of
     * <cite>The Java Language Specification</cite>.
Run Code Online (Sandbox Code Playgroud)

调用这个方法实际上有什么用处吗?因为它是final,子类不能重写它以使其执行任何不同的操作。它实际上是一个除了空检查之外什么都不做的方法,还是 JVM 是否以某种方式神奇地拦截了它的调用并执行更多操作?

Ste*_*n C 6

调用这个方法实际上有什么用处吗?

在 Java 8 中,该方法称为本机方法resolveClass0。我还没有研究过 Java 8 原生方法的实现。它可能已经是一个空操作了。

从 Java 9 开始,它只是检查参数c是否不是null。所以……现在,答案显然是否定的。

Java 8 和 9 之间的类加载器的实现发生了重大变化(请参阅https://www.oracle.com/java/technologies/javase/9 ​​-all-relnotes.html )。这部分是由于需要支持 Java 9 模块。

我的猜测是,Java 9 类加载器的更改使该resolveClass方法变得多余或无用。但 Java 团队并没有给使用自定义类加载器的人带来返工,而是简单地将方法变成了无操作。

无论如何,javadoc 评论说:

链接指定的类。类加载器可以使用此(名称误导性的)方法来链接类。如果该类c已被链接,则此方法仅返回。否则,该类将按照“Java 语言规范”的“执行”一章中的描述进行链接。

我现在可以想到使该方法成为无操作的两种可能的解释:

  1. 在当前(Java 9+)类加载器实现中,类总是可以更早链接,从而使调用变得多余。

  2. 他们决定不再允许自定义类加载器决定何时链接该类。

    • 也许它会导致在更新的类加载器实现中难以处理的复杂性?
    • 也许这被认为是原始设计中的缺陷?