public class Test { public static void main(String[] args) throws ClassNotFoundException { new Test().test(); } public void test() throws ClassNotFoundException { // Java应用的类都是由它来完成加载 System.out.println(this.getClass().getClassLoader()); // sun.misc.Launcher$AppClassLoader@2a139a55 System.out.println(this.getClass().getClassLoader().getParent());// sun.misc.Launcher$ExtClassLoader@7852e922 // 编译生成的.class文件的bin目录 String path = System.getProperty("java.class.path"); } }
关于系统类加载器与自定义加载器注意以下几点:
MyClassLoader 为自定义类加载器,相关代码,自已可以百度一下。
(1)一个类加载器实例可以加载多个类
// myClassLoader1 为自定义类加载器实例 MyClassLoader myClassLoader1 = new MyClassLoader(); Class<?> clazz1 = myClassLoader1.findClass("com.classloader.PrintServiceImpl"); Class<?> clazz3 = myClassLoader1.findClass("com.classloader.ClassFile");
(2)但是对于同一个类型,一个类加载器实例只能加载一次,下面这个就会抛出异常:
Exception in thread "main" java.lang.LinkageError: loader (instance of com/classloader/MyClassLoader): attempted duplicate class definition for name: "com/classloader/PrintServiceImpl" at java.lang.ClassLoader.defineClass1(Native Method)
MyClassLoader myClassLoader1 = new MyClassLoader(); Class<?> clazz1 = myClassLoader1.findClass("com.classloader.PrintServiceImpl"); Class<?> clazz2 = myClassLoader1.findClass("com.classloader.PrintServiceImpl");
异常:一个本地方法异常;LinkageError:
(3)对于同一个类型若要加载多次,只能通过不同的类加载器的实例来加载
添加虚拟机参数:-verbose:class
MyClassLoader myClassLoader1 = new MyClassLoader(); Class<?> clazz1 = myClassLoader1.findClass("com.classloader.PrintServiceImpl"); MyClassLoader myClassLoader2 = new MyClassLoader(); Class<?> clazz2 = myClassLoader2.findClass("com.classloader.PrintServiceImpl"); System.out.println(clazz1==clazz2); // false // 因为myClassLoader1 = clazz1.getClassLoader(),所以下面打印必为false ; System.out.println(clazz1.getClassLoader()==clazz2.getClassLoader());// false // myClassLoader1.getClass()的值为java.lang.Class,所以下面必为true System.out.println(clazz1.getClassLoader().getClass()==clazz2.getClassLoader().getClass());// true // myClassLoader1.getParent(); System.out.println(clazz1.getClassLoader().getParent()==clazz2.getClassLoader().getParent());// true
(4)Class.forName("")加载一次(并且会执行初始化操作)
Class.forName("com.classload.Student"); Class<?> clazz1 = Class.forName("com.classload.Student"); Class<?> clazz2 = Class.forName("com.classload.Student"); System.out.println(Class.forName("com.classload.Student")==clazz1);// true System.out.println(clazz1); // class com.classload.Student System.out.println(clazz2); // class com.classload.Student System.out.println(clazz1==clazz2); // true
原文:https://www.cnblogs.com/caoxb/p/12735523.html