显式加载 - java.lang.ClassLoader

Explicit loading - java.lang.ClassLoader

在第一种情况下,使用下面的代码显式加载 test.ClassLoaderTest

public ClassLoaderTest{
      public static void main(String[] args){
        .....
        Class.forName("test.ClassLoaderTest", true,
                          ClassLoaderTest.class.getClassLoader().getParent());
        ....
      }

findClass() Launcher$ExtClassLoader 实例的方法被调用以加载 test.ClassLoaderTest 由于可见性原则出现以下错误,

java.lang.ClassNotFoundException: test.ClassLoaderTest
at java.net.URLClassLoader.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at test.ClassLoaderTest.main(ClassLoaderTest.java:29)

在第二种情况下,在显式加载 test.ClassLoaderTest1 时,使用

public ClassLoaderTest{
          public static void main(String[] args){
            .....
            Class.forName("test.ClassLoaderTest1");
            ....
          }

loadClass()实例的Launcher$AppClassLoader方法最终用于加载test.ClassLoaderTest1class,

其中 test.ClassLoaderTest1 是导致以下错误的错误 class 文件,

java.lang.ClassNotFoundException: test.ClassLoaderTest1
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at test.ClassLoaderTest1.main(ClassLoaderTest.java:16)

在这两种情况下,class 加载作业由 java.net.URLClassLoader.findClass()

完成

Class.forName() 内部调用 getClassLoader() 以了解已经加载 class.

的 class 加载程序

在第二种情况下,当 Class 通过调用获取 class 加载器实例(类型为 Launcher$AppClassLoader) ClassLoader cl = getClassLoader0(); 再次调用 class 加载器实例。

java.lang.ClassLoader主要用于子class自定义class加载器吗?该负载 class 在 CLASSPATH 中不可用,但来自网络源等...

来自 Javadoc,

public **abstract** class ClassLoader
extends Object

有不同的 ClassLoader 实现使用不同的策略来定位和读取组成 class 的字节流。