类加载器在尝试自己去查找某个类的字节代码并定义它时,会先代委托给其父类加载器,由父类加载器先去尝试加载这个类,依次类推。在介绍委托模式背后的动机之前,首先需要说明一下 Java 虚拟机是如何判定两个 Java 类是相同的。Java 虚拟机不仅要看类的全名是否相同,还要看加载此类的类加载器是否一样。只有两者都相同的情况,才认为两个类是相同的。即便是同样的字节代码,被不同的类加载器加载之后所得到的类,也是不同的。比如一个 Java 类com.tao.test.
ClassTest,编译之后生成了字节代码文件ClassTest.class
。两个不同的类加载器ClassLoaderA
和
ClassLoaderB
分别读取了这个ClassTest.class
文件,并定义出两个java.lang.Class
类的实例来表示这个类。这两个实例是不相同的。对于 Java 虚拟机来说,它们是不同的类。试图对这两个类的对象进行相互赋值,会抛出运行时异常ClassCastException
。下面通过上面一讲的示例来具体比较
结果是:
类加载器是怎么进行委托的呢,我们可以查看下ClassLoader的源码分析下。
因为,在加载一个类的时候,都是调用loadClass()方法,所以具体看下loadClass()方法。
所以,可以很清楚的看到,加载一个类的过程,它是层层的像父类委托,然后在层层的向下加载。用这样的一种委托机制,到底有什么好处呢?为什么要这样做呢?
原因如下:
1、节约系统资源。只要,这个类已经被加载过了,就不会在次加载。
2、保证 Java 核心库的类型安全。所有 Java 应用都至少需要引用 java.lang.Object
类,也就是说在运行的时候,java.lang.Object
这个类需要被加载到 Java 虚拟机中。如果这个加载过程由 Java 应用自己的类加载器来完成的话,很可能就存在多个版本的
java.lang.Object
类,而且这些类之间是不兼容的。通过代理模式,对于 Java 核心库的类的加载工作由引导类加载器来统一完成,保证了 Java 应用所使用的都是同一个版本的 Java 核心库的类,是互相兼容的。
分享到:
相关推荐
C中实现单例模式7.4 子类化Singleton7.5 线程安全7.6 在Cocoa Touch框架中使用单例模式7.6.1 使用UIApplication类7.6.2 使用UIAccelerometer类7.6.3 使用NSFileManager类7.7 总结第三部分 接口适配第8章 适配器8.1 ...
│ 高并发编程第二阶段48讲、JVM内置三大类加载器的详细介绍.mp4 │ 高并发编程第二阶段49讲、自定义类加载器ClassLoader顺便问候了一下世界.mp4 │ 高并发编程第二阶段50讲、ClassLoader父委托机制详细介绍.mp4 ...
│ 高并发编程第二阶段48讲、JVM内置三大类加载器的详细介绍.mp4 │ 高并发编程第二阶段49讲、自定义类加载器ClassLoader顺便问候了一下世界.mp4 │ 高并发编程第二阶段50讲、ClassLoader父委托机制详细介绍.mp4 ...
python入门到高级全栈工程师培训视频学习资料;本资料仅用于学习,请查看后24小时之内删除。 【课程内容】 第1章 01 计算机发展史 02 计算机系统 03 小结 04 数据的概念 05 进制转换 06 原码补码反码 07 物理层和...
├─(100) 04 python全栈3 day54 Django内容回顾(三).avi ├─(101) 05 python全栈3 day54 Django请求生命周期之Http请求.avi ├─(102) 06 python全栈3 day54 Django请求生命周期之FBV和CBV.avi ├─(103) 07 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...
2.4.1 委托回顾 40 2.4.2 匿名方法 42 2.4.3 Lambda表达式介绍 42 2.5 扩展方法 47 2.5.1 创建扩展方法的示例 47 2.5.2 更多使用LINQ标准查询操作符的例子 50 2.5.3 将扩展方法引入到实例程序中 51 ...