文章插图
?
大家看下类加载系统-图一和类加载系统-图二,作者建立了一个类,这个类是和Java自身提供的java.lang.String是一样的包名和类名 。
可以想象一下如果这个类成功执行了,那么接下来如果有别的类在引用的时候,应该先引用作者写的这个,还是引用Java自身的java.lang.String类?
如:以上的例子大家都知道,垃圾袋的颜色已经统一成一模一样了,有一天A商家在门口放了两袋垃圾袋,一袋是装着打碎的瓷盘碎片,一袋是装着厨房的垃圾,都绑着 。
马上就要下班了,员工准备拿垃圾袋去扔,由于垃圾袋绑着,这位员工赶着去约会,直接往垃圾袋随时一抓,好了,结果大家猜到了,于是在第二天员工聪明了向商家要求,由于垃圾袋颜色一样,要求垃圾袋贴上小纸条,标明哪个垃圾袋是装什么的,这样做的之后,提高了安全性,而且又能够保证在做垃圾分类的时候可以保证各个垃圾袋放的东西是按照垃圾分类的要求放的 。
是什么?
类装载系统是由数个加载器组成的,负责将class文件信息加载进内存,存放在数据区-方法区内 。
执行过程

文章插图

文章插图
?
加载:通过完全限定名查找到这个类的字节码文件,将其静态的存储结构转化虚拟机的方法区运行时数据结构,并生成一个代表这个类的对象,这个就是为什么可以进行反射操作 。
类加载过程:

文章插图

文章插图
?
为什么要这样加载?
当类在加载的时候,如类加载系统-图一,定义一个java.lang.String是一样的包名和类名,而类加载的时候是通过限定名去查找这个类字节码文件的,那样就出现了相同的内容,那么则出现了冲突,破坏了Java内部的完整性以及一致性 。
在类加载系统-图二中我们可以看到,类加载器是有父类的,所以在↑查找的时候,是查找类是否已经在启动等过程中,已启动的加载器加载了,如果查找到的所有加载器都没有加载,那么则向下查找,哪个加载器是可以加载到这个类的,而这个也叫做双亲委派机制,而Tomcat、Jboss都依照Java规范有着实现了加载器 。
双亲委派机制:可以理解为不止是坑爹的,且还是坑到爷一代的,在接到一个类加载的请求的时候,会先问他爹加载了没有,他爹会问他爷加载了没有,他爷也没有加载,那么就会给回去,最后就只好自己加载了,也就是只有父类无法完成的任务才自己完成 。
验证:文件格式验证、元数据验证、字节码验证、符号引用验证,目的在于确保字节码文件内的信息符合虚拟机的要求并不会破坏到虚拟机的内容(虚拟机的一致性,完整性) 。
准备:为类变量(静态变量)分配对应的内存,并设置这些类变量的值,这些内存是分配方法区的内存,但设置的这些类变量的值,具体要看是否有final修饰符,如果没有那么则无论值是多少都是为0,如果修饰符有final,那么设置的这个值则就是类变量的值 。
解析:将符号引用转化为直接引用,符号引用就是通过对应的符号找到目标对象,符号可以是字面量,符号引用和虚拟机内存的布局是无关的,因符号引用的对象可以不加载到内存里,直接引用就是存在于内存中的,是有指针可以指向到的 。
虚拟机没有规定解析的时间,只需要在anew arry、check cast、get field、instance of、invoke interface、invoke special、invoke static、invoke virtual、multi anew array、new、put field和put static这13个用于操作符号引用指令执行之前,对符号引用进行解析 。
所以虚拟机会判断是在类被加载器加载的时候对符号引用进行解析还是等符号引用在要被使用前去解析,可以通过看上面的13个指令去得到答案 。
解析的东西主要是类、接口、字段、类方法、接口方法这五类进行解析 。
无非就是不管你这个类是接口还是实现类,还是什么,只要你是个类,那么就解析你里面的所有内容 。
推荐阅读
- javascript中的事件
- 哇塞!GitHub 上这些 Java repo 太强了吧,看完都变大佬
- 一名高级的Javaer,应该了解的 MYSQL 高级知识点
- 我也没想到,Java开发 API接口可以不用写 Controller了
- Java中的封装、继承和多态,你真的都懂了吗
- 什么是 Java 的无服务器化?
- Javascript实现两变量值的互换
- java按顺序执行线程
- linux系统上查看载体为实体机还是虚拟机
- 线程安全问题无大小:Java中的线程安全之操作共享数据分类
