一、类加载器的层次结构java
在双亲委托机制中,各个加载器按照父子关系造成了树形结构(逻辑意义),除了根加载器以外,其他的类加载器都有且只有一个父加载器。jvm
public class MyTest13 { public static void main(String[] args) { ClassLoader classLoader = ClassLoader.getSystemClassLoader(); System.out.println(classLoader); while (null != classLoader){ classLoader = classLoader.getParent(); System.out.println(classLoader); } } }
打印结果ui
sun.misc.Launcher$AppClassLoader@18b4aac2 sun.misc.Launcher$ExtClassLoader@1540e19d null
null说明classLoader是启动类加载器url
二、类加载器的双亲委托机制spa
三、返回String类的ClassLoader线程
public class MyTest7 { public static void main(String[] args) throws Exception{ Class<?> clazz = Class.forName("java.lang.String"); ClassLoader classLoader = clazz.getClassLoader(); System.out.println(classLoader); } }
返回结果blog
null
null说明classLoader是启动类加载器ssl
四、返回自定义类的ClassLoaderget
public class MyTest7 { public static void main(String[] args) throws Exception{ Class<?> clazz2 = Class.forName("com.example.jvm.classloader.C"); ClassLoader classLoader2 = clazz2.getClassLoader(); System.out.println(classLoader2); } } class C{ }
返回结果io
sun.misc.Launcher$AppClassLoader@18b4aac2
五、得到class文件的路径
public class MyTest14 { public static void main(String[] args) throws IOException{ ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); System.out.println(classLoader); String resourceName = "com/example/jvm/classloader/MyTest13.class"; Enumeration<URL> urls = classLoader.getResources(resourceName); while (urls.hasMoreElements()){ URL url = urls.nextElement(); System.out.println(url); } } }
打印结果:
sun.misc.Launcher$AppClassLoader@18b4aac2 file:/D:/workspace/study/%20jvm_demo/build/classes/java/main/com/example/jvm/classloader/MyTest13.class
六、得到ClassLoader的途径
得到当前类的ClassLoader
clazz.getClassLoader();
得到当前线程的上下文ClassLoader
Thread.currentThread().getContextClassLoader()
得到系统的ClassLoader
ClassLoader.getSystemClassLoader();
得到调用者的ClassLoader
DriverManager.getCallerClassLoader()