This method is first invoked early in the runtime's startup * sequence, at which point it creates the system class loader and sets it * as the context class loader of the invoking Thread. *此方法在运行期的早期就会被调用,在这个时间点创建系统类的加载器,并且设定其为调用线程的上下文的一个类加载器。 *
The default system class loader is an implementation-dependent * instance of this class. *默认的系统类加载器与这个类实现相关的实例 *
If the system property "java.system.class.loader" is defined * when this method is first invoked then the value of that property is * taken to be the name of a class that will be returned as the system * class loader. The class is loaded using the default system class loader * and must define a public constructor that takes a single parameter of * type ClassLoader which is used as the delegation parent. An * instance is then created using this constructor with the default system * class loader as the parameter. The resulting class loader is defined * to be the system class loader. * 如果设定了java.system.class.loader那么这个方法返回的就是java.system.class.loader设定的类加载器。这个类被系统类加载器加载,并且 * 定义一个公共的构造方法,接受一个ClassLoader参数用作为委托的双亲,用默认系统类类加载器作为构造器的参数,就会创造一个实例 ,所得到的就是系统类加载器 */ //返回系统类加载器 @CallerSensitive public static ClassLoader getSystemClassLoader() { initSystemClassLoader(); if (scl == null) { return null; } SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkClassLoaderPermission(scl, Reflection.getCallerClass()); } return scl; } ``` > getParent方法: ```java /** * Returns the parent class loader for delegation. Some implementations may * use null to represent the bootstrap class loader. This method * will return null in such implementations if this class loader's * parent is the bootstrap class loader. * 返回父加载器用于委托,有些实现返回null用来表示根类加载器,如果一个类的父加载器是根加载器,那么这个方法将会返回null */ public final ClassLoader getParent() { if (parent == null) return null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { // Check access to the parent class loader // If the caller's class loader is same as this class loader, // permission check is performed. checkClassLoaderPermission(parent, Reflection.getCallerClass()); } return parent; } ``` > parent 变量是ClassLoader的成员变量: ```java // The parent class loader for delegation // Note: VM hardcoded the offset of this field, thus all new fields // must be added *after* it. 用于委托的双亲加载器,JVM将这个变量的偏移量进行了硬编码,,这样新的变量就要加载这个变量的后边 private final ClassLoader parent; ``` > 下一例子: 如何通过一个给定的字节码的路径来把相应的资源信息打印出来 ```java public class MyTest14 { public static void main(String[] args) throws IOException { //Thread.currentThread():或取到当前执行的线程一个引用 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();//通常用于启动应用的应用类加载器 String resourceName = "com/twodragonlake/jvm/classloader/MyTest13.class";//包名 /* Finds all the resources with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code. 返回给定名字所有的资源,资源可以是(图片,音频,文本,等)可以被class字节码以一种与字节码位置无关的方式去访问, classLoader.getResources(resourceName){....} */ Enumeration urls = classLoader.getResources(resourceName);//找到给定名字的所有资源 while(urls.hasMoreElements()){ System.out.println(urls.nextElement()); } System.out.println("----------------"); Class> clazz = String.class; System.out.println(clazz.getClassLoader());//自定义的类有系统类加载器加载 System.out.println("----------------"); clazz = MyTest14.class; System.out.println(clazz.getClassLoader()); //由根类加载器加载 因为系统类加载器的加载目录包含rt目录 } } ``` > 运行结果 ```java file:/E:/Study/intelIde/jvm_lecture/out/production/classes/com/twodragonlake/jvm/classloader/MyTest13.class ---------------- null ---------------- sun.misc.Launcher$AppClassLoader@18b4aac2 ``` > **获取`ClassLoader`的方式** 获得当前类的`ClassLoader`: `class.getClassLoader()`; 获取当前线程上下文的`ClassLoader`: `Thread.currentThread().getContextClassLoader();` 获得系统的`ClassLoader`: `ClassLoader.getSystemClassLoader()` 获得调用者的`ClassLoader`: `DriverManager.getCallerClassLoader();` 类加载器不是用来加载对象的,是加载和对象对应的类。 class对象对应的是类本身 ### 类加载器的双亲委托机制 ![不同的类加载器作用与加载动作分析02.png][2] 如果感觉本篇看着还不是太懂可以看下篇博客:[不同的类加载器作用与加载动作分析](https://www.cnblogs.com/webor2006/p/9029910.html),这篇小编就先不进行复制了。直接点击链接就可以跳到原文。 附:[参考原文1](https://ceaser.wang/2018/10/04/jvm%E5%8E%9F%E7%90%86%EF%BC%888%EF%BC%89%E4%B8%8D%E5%90%8C%E7%9A%84%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8%E4%B8%8E%E5%8A%A0%E8%BD%BD%E4%B8%8E%E5%8A%A0%E8%BD%BD%E5%8A%A8%E4%BD%9C%E5%88%86%E6%9E%90/),[参考原文2](https://www.cnblogs.com/webor2006/p/9029910.html)。 [1]: https://lilinchao.com/usr/uploads/2019/12/4152142786.png [2]: https://lilinchao.com/usr/uploads/2019/12/4238738204.png
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://lilinchao.com/archives/236.html
评论已关闭