扩展类载入器的载入问题
我们都知道java的类载入器共同拥有三级,各自是bootstrap (引导类)载入器、extension(扩展类)载入器和 system (系统类)载入器。这三个载入器是父子关系,当中 bootstrap 类载入器在顶端,而 system 载入器在结构的最底层。同一时候他们都採取向上传递的机制,即有了要载入的类,先问问自己的父载入器,若父载入器不能载入,自己再载入。
我们写了一个helloworld类,载入的时候,二进制字节码送给系统类载入器,可是系统类会询问它的父载入器(扩展类)你能载入不?扩展类载入器也会询问自己的父载入器(引导类)你能载入不?
通俗的说,引导扩展系统三个载入器就像爷爷父亲孙子一样,他们载入非常孝顺,载入类的时候都先让长辈载入,长辈不能载入自己才会去载入。
这样做有什么优点么?
假设你写了一个全名为java.lang.Object的类,里面有一些危急代码,载入时首先会是系统类载入器尝试载入..最后是引导类来载入,它会依照路径直接去C:\Program Files\Java\jdk1.7.0_15\jre\lib\rt.jar这个位置里去找java.lang.Object。总而言之,安全!
执行结果
boot C:\Program Files\Java\jdk1.7.0_15\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\rt.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_15\jre\classes
ext C:\Program Files\Java\jdk1.7.0_15\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
system .;C:\Program Files\Java\jdk1.7.0_15\lib\dt.jar;C:\Program Files\Java\jdk1.7.0_15\lib\tools.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\rt.jar;E:\apache-tomcat-7.0.47_8700\lib\servlet-api.jar;
sun.misc.Launcher$AppClassLoader@fb56b1PPP
通过上面的样例,大家就知道了三级载入器的载入范围;
如今我有一个想法,假设咱们把Property类的class文件放到扩展类载入器的文件夹下,那它是不是就会被扩展类载入器所载入呢?
如今我们至少能知道几个问题
我们写了一个helloworld类,载入的时候,二进制字节码送给系统类载入器,可是系统类会询问它的父载入器(扩展类)你能载入不?扩展类载入器也会询问自己的父载入器(引导类)你能载入不?
通俗的说,引导扩展系统三个载入器就像爷爷父亲孙子一样,他们载入非常孝顺,载入类的时候都先让长辈载入,长辈不能载入自己才会去载入。
这样做有什么优点么?
假设你写了一个全名为java.lang.Object的类,里面有一些危急代码,载入时首先会是系统类载入器尝试载入..最后是引导类来载入,它会依照路径直接去C:\Program Files\Java\jdk1.7.0_15\jre\lib\rt.jar这个位置里去找java.lang.Object。总而言之,安全!
public class Property { public static void main(String[] args) { System.out.println("boot "+System.getProperty("sun.boot.class.path")); System.out.println("ext "+System.getProperty("java.ext.dirs")); System.out.println("system "+System.getProperty("java.class.path")); try { System.out.println(Class.forName("Property").getClassLoader()+"PPP"); } catch (Exception e) { e.printStackTrace(); } } }
执行结果
boot C:\Program Files\Java\jdk1.7.0_15\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\rt.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_15\jre\classes
ext C:\Program Files\Java\jdk1.7.0_15\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
system .;C:\Program Files\Java\jdk1.7.0_15\lib\dt.jar;C:\Program Files\Java\jdk1.7.0_15\lib\tools.jar;C:\Program Files\Java\jdk1.7.0_15\jre\lib\rt.jar;E:\apache-tomcat-7.0.47_8700\lib\servlet-api.jar;
sun.misc.Launcher$AppClassLoader@fb56b1PPP
通过上面的样例,大家就知道了三级载入器的载入范围;
如今我有一个想法,假设咱们把Property类的class文件放到扩展类载入器的文件夹下,那它是不是就会被扩展类载入器所载入呢?
ok,我把Property类的class文件放到扩展类载入器的文件夹下,结果不变;
奇怪了,不是说好了扩展载入器载入 C:\Program Files\Java\jdk1.7.0_15\jre\lib\ext这个文件夹下的文件吗?
要不,压缩成jar文件?
要不,换个压缩方式?
如今我们至少能知道几个问题
1 在扩展类载入器的载入文件夹下,仅仅认jar格式的文件,class文件不看
2 jar还得是zip的压缩格式!
.... 就为了这么一点小问题 我花了快2个小时 羞愧