这适用于 Java 8:
public class Test {
public static void main(String[] args) throws Exception {
URLClassLoader loader = new URLClassLoader(new URL[0], null);
System.out.println("" + loader.loadClass("java.sql.Driver"));
}
}
但是使用 Java 17 会抛出 ClassNotFoundException:
Exception in thread "main" java.lang.ClassNotFoundException: java.sql.Driver
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
at Test.main(Test.java:16)
Java 17 的优秀类加载器图:
https://medium.com/@wakefulinsomnia/how-does-java-classloader-system-work-82eaf378f73b
相关/类似问题:
我目前的理解是,如果使用 null 父级,实际上只有 java 基类加上 URL[] 参数中的类可用。
如果还需要“java.sql”等模块中的“非基本”类,那么至少需要使用
jdk.internal.loader.ClassLoaders$PlatformClassLoader
作为父类。
public class Test {
public static void main(String[] args) throws Exception {
System.out.println("java.version : " + System.getProperty("java.version"));
System.out.println("Test.class.getClassLoader() : " + Test.class.getClassLoader());
System.out.println("ClassLoader.getSystemClassLoader() : " + ClassLoader.getSystemClassLoader());
System.out.println("ClassLoader.getSystemClassLoader().getParent() : " + ClassLoader.getSystemClassLoader().getParent());
System.out.println("ClassLoader.getSystemClassLoader().getParent().getParent(): " + ClassLoader.getSystemClassLoader().getParent().getParent());
ClassLoader platformClassLoader = ClassLoader.getSystemClassLoader().getParent();
System.out.println(platformClassLoader.getClass());
URLClassLoader loader = new URLClassLoader(new URL[0], platformClassLoader);
System.out.println("loader.loadClass('java.sql.Driver') : " + loader.loadClass("java.sql.Driver"));
}
}
Java 8 输出:
java.version : 1.8.0_382
Test.class.getClassLoader() : sun.misc.Launcher$AppClassLoader@4e0e2f2a
ClassLoader.getSystemClassLoader() : sun.misc.Launcher$AppClassLoader@4e0e2f2a
ClassLoader.getSystemClassLoader().getParent() : sun.misc.Launcher$ExtClassLoader@2a139a55
ClassLoader.getSystemClassLoader().getParent().getParent(): null
class sun.misc.Launcher$ExtClassLoader
loader.loadClass('java.sql.Driver') : interface java.sql.Driver
Java 17 输出:
java.version : 17.0.8
Test.class.getClassLoader() : jdk.internal.loader.ClassLoaders$AppClassLoader@659e0bfd
ClassLoader.getSystemClassLoader() : jdk.internal.loader.ClassLoaders$AppClassLoader@659e0bfd
ClassLoader.getSystemClassLoader().getParent() : jdk.internal.loader.ClassLoaders$PlatformClassLoader@3fee733d
ClassLoader.getSystemClassLoader().getParent().getParent(): null
class jdk.internal.loader.ClassLoaders$PlatformClassLoader
loader.loadClass('java.sql.Driver') : interface java.sql.Driver