我们知道我们可以用以下方式覆盖System 类加载器:
java -Djava.system.class.loader=com.test.MyClassLoader xxx
Run Code Online (Sandbox Code Playgroud)
那么,因为com.test.MyClassLoader它本身就是一个类,它是由谁加载的?
我们如何获得这个"meta"类加载器的类文件?
ami*_*ngh 24
Bootstrap classloader是all的父级,classloaders并在JRE(rt.jar和i18n.jar)的lib目录中加载标准JDK类.所有java.*类都由此加载classloader.
Extensions Classloader是Bootstrap类加载器的直接子代.此类加载器加载JRE的lib\ext目录中的类.
System-Classpath classloader是Extensions类加载器的直接子项.它加载CLASSPATH环境变量指定的类和jar
您可以尝试通过"java.system.class.loader"属性注入自定义类加载器(请参阅ClassLoader#getSystemClassLoader).
Default System class loader 是MyClassLoader实例的父级,
cas*_*nca 19
来自Javadoc ClassLoader.getSystemClassLoader:
如果在首次调用此方法时定义了系统属性"java.system.class.loader",那么该属性的值将被视为将作为系统类加载器返回的类的名称.使用默认的系统类加载器加载该类,并且必须定义一个公共构造函数,该构造函数接受一个类型为ClassLoader的参数,该参数用作委托父级.
默认的系统类加载器本身特定于JVM实现.
§ ..该属性的值被视为将作为系统类加载器返回的类的名称.使用默认的系统类加载器加载该类.
..因此,如果您的类加载器将X替换为系统类加载器,那么您的类加载器的父级将是X,即默认的系统类加载器.
(X的类型是sun.misc.Launcher$AppClassLoader.)
更多信息可以在docs.oracle.com找到- Java Launcher如何查找类:
Java启动程序java启动Java虚拟机.虚拟机按以下顺序搜索并加载类:
Bootstrap类 - 构成Java平台的类,包括rt.jar中的类和其他几个重要的jar文件.
扩展类 - 使用Java扩展机制的类.它们捆绑为扩展目录中的.jar文件.
用户类 - 由开发人员和第三方定义的不利用扩展机制的类.您可以使用CLASSPATH环境变量在命令行上使用-classpath选项标识这些类的位置.
我们可以证明X确实是我们的父母Classloader:
/** run with -Djava.system.class.loader=MyCL to use this classloader */
public class MyCL extends ClassLoader {
public MyCL(ClassLoader parent) { // this constructor must be public, else IllegalAccessException
super(parent);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我们的主要代码:
public class Main {
public static void main(String args[]) {
System.out.println("getSystemClassLoader(): " + ClassLoader.getSystemClassLoader());
ClassLoader cl = MyCL.class.getClassLoader();
System.out.println("Classloader of MyCL: " + cl);
Class type_of_cl = cl.getClass();
System.out.println("..and its type: " + type_of_cl);
ClassLoader cl_of_cl = class_of_cl.getClassLoader();
System.out.println("Classloader of (Classloader of MyCL): " + cl_of_cl);
}
}
Run Code Online (Sandbox Code Playgroud)
这是使用命令运行时的输出(在我的系统上)java -Djava.system.class.loader=MyCL Main(参见Eclipse运行配置):
getSystemClassLoader():MyCL @ 1888759 MyCL的
类加载器:sun.misc.Launcher$AppClassLoader@7fdcde
..及其类型:class sun.misc.Launcher $ AppClassLoader
(Classloader of MyCL)的类加载器:null
我们可以看到MyCLclassloader是sun.misc.Launcher$AppClassLoader,它是默认的系统类加载器.
(根据上面Oracle的其他引用中所见的语言,默认的系统类加载器也称为" 用户类 " 的类加载器.螺丝Oracle为同一件事提出2个名称.)