类加载器命名空间总结与扩展类加载器要点分析
类加载器命名空间总结:
类加载器的双亲委托模型的好处:
- 可以确保Java核心库【如JDK中rt.jar里面的类】的安全:所有的Java应用至少会引用java.lang.Object类,也就是说在运行期,java.lang.Object这个类会被加载到Java虚拟机中;如果这个加载过程是由Java应用自己的类加载器所完成的,那么很可能就会在JVM中存在多个版本的java.lang.Object类,而且这些类之间还是不兼容的,相互不可见的(正是命名空间在发挥着作用)。所以可见是有很多的问题的,而借助于双亲委托机制,Java核心类库中的加载工作都是由启动类加载器来统一完成,从而确保了Java应用所使用的都是同一个版本的Java核心类,他们之间是相互兼容的。
- 可以确保Java核心类库所提供的类不会被自定义的类所替代,这样避免威胁JDK中的一些系统类:比如咱们自己定义了一个java.lang.Object,它是无论如何都不会被加载到JVM当中的,因为它一定是启动类加载器去加载,而没有机会去加载咱们自定义的Object类。
- 不同的类加载器可以为相同名称(binary name)的类创建额外的命名空间,相同名称的类可以并存在java虚拟机中,只需要用不同的类加载器来来加载他们既可。不同的类加载器所加载的类之间是不兼容的,这就相当于在Java虚拟机的内部创建了一个又一个相互隔离的Java类空间,这类技术在很多框架中都得到了实际应用。
扩展类加载器要点分析:
在上一次【https://www.cnblogs.com/webor2006/p/9157626.html】中已经演示了一个扩展类加载器的类,回顾一下:
这次继续来探讨一下它,下面来编写测试代码:
不多解释,而我们知道扩展类加载器所加载的路径为:
那如果我们将java.ext.dirs所对应的路径改为我们工程的目录是否我们自定义的类就可以由扩展类加载器所加载而不是默认的应用类加载器加载了呢?下面来实验一下:
根据类加载器的双亲委托机制照理应该是委托给扩展类加载器所加载的呢,这是为什么呢?这是因为扩展类加载器有些特殊,它加载的类是需要打成jar包的,所以咱们将MyTest1类打成jar包,具体如下:
所以此时工程中既有MyTest1.class文件,也有一个test.jar中包含了MyTest1.class,下面再来运行:
下面再来改造一下:
其它一切不变,那此时输出又如何呢?