类加载器

 类加载器的种类:
(1)BootStrap启动类加载器,加载jdk/jre/lib下的类
(2)extention扩展类加载器,其父加载器为启动类加载器,加载jdk/jre/lib/ext下的类
(3)application(system)应用类加载器,其父加载器为扩展类加载器,加载classpath路径下的类
(4)自定义类加载器

类加载器的三大特性:
(1)委托性:当类A 被加载时,application类加载器会委托给父类加载器extention类加载器,extention类加载器会委托给BootStrap加载器;
    BootStrap加载器会在jdk/jre/lib下查找是否会存在该类,如果存在,那么加载它。如果不存在,那么就又会回到extention加载器;
    extention加载器会查看在jdk/jre/lib/ext下是否存在该类,如果存在则加载,如果不存在,那么就会回到application类加载器加载;
    application类加载器会查找classpath路径下是否存在类A,如果存在则加载,如果不存在,则会报ClassNotFoundException异常。
(2)可见性:由父类加载器加载的类可以被子类观察到,但是由子类加载的类对父类加载器不可见。
(3)单一性:一个类只可以被加载一次。


显示的加载类:
java提供了显示加载类的API:
Class.forName(String className) 注意参数是全限定类名
Class.forName(String name, boolean initialize,ClassLoader loader)

ClassNotFoundException:
此异常是在类不能被正常加载的时候报的异常。以下几种情况可能会报出此异常:
Class.forName(String className) 注意参数是全限定类名
Class.forName(String name, boolean initialize,ClassLoader loader)

public class ClassLoaderTest {

    public void m() throws Exception {
        Class.forName("com.bonnie.ClassLoad.ClassLoaderTes");//故意写错ClassLoaderTest类的名字,就会报ClassNotFoundException
        Class.forName("com.bonnie.ClassLoad.ClassLoaderTest", true, ClassLoaderTest.class.getClassLoader().getParent());//如果用父加载器(ClassLoaderTest.class.getClassLoader().getParent())加载就会报ClassNotFoundException
    }

    public void m2() {
        /**
         * 获取当前类的类加载器
         */
        java.lang.ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
        System.out.println(classLoader);//打印输出:sun.misc.Launcher$AppClassLoader@18b4aac2
        java.lang.ClassLoader classLoader1 = ClassLoader.getSystemClassLoader();
        System.out.println(classLoader1);//打印输出:sun.misc.Launcher$AppClassLoader@18b4aac2
    }
}
public static void main(String[] args) throws Exception {
    ClassLoaderTest classLoaderTest=new ClassLoaderTest();
    classLoaderTest.m();
}

 报错:

Exception in thread "main" java.lang.ClassNotFoundException: com.bonnie.ClassLoad.ClassLoaderTest
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.bonnie.ClassLoad.ClassLoaderTest.m(ClassLoaderTest.java:56)
at com.bonnie.ClassLoaderTest.main(ClassLoaderTest.java:64)

 

NoClassDefFoundException:
此异常是在编译时正常,但在运行时找不到此类。比如将编译后的某个class文件删掉,jvm不能找到这个类就会报这个异常。

public static void main(String[] args) throws Exception {
    TestEntity testEntity=new TestEntity("s");
}

如果将TestEntity.class文件从target文件夹中删掉,就会报以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: com/bonnie/Entity/TestEntity
at com.bonnie.ClassLoad.ClassLoaderTest.main(ClassLoaderTest.java:80)
Caused by: java.lang.ClassNotFoundException: com.bonnie.Entity.TestEntity
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

原文地址:https://www.cnblogs.com/BonnieWss/p/10978408.html