java类的生命周期:

加载->验证->准备->解析->初始化->使用->卸载
其中从加载到初始化称为类加载。而验证准备和解析可以称为链接阶段。
加载阶段:先判断该类有没有被加载,没有则由类加载器根据一个类的全限定类名
从硬盘上读取此类的二进制字节流到jvm内部,然后存储在方法内,并且根据这个
二进制字节流文件创建一个java.lang.class对象,这个对象中保存了这个类的全部信息。
类加载器(classLoader)生存地点在jvm的堆中。
类加载器的双亲委派模式:
类加载器的类型:
1.启动类加载器(BootStrap ClassLoader),负责将<Java_Runtime_Home>/lib下面的类库加载
到内存中。
2.扩展类加载器(Extension ClassLoader),负责将<Java_Runtime_Home>/lib/ext或者由系统
变量java.ext.dir指定位置中的类库加载到内存中
3.系统类加载器(ApplicationClassLoader):负责将系统类路径(CLASSPATH)中指定的类库加载到
内存中。
4.自定义类加载器
jvm的加载器顺序是:BootStrap ClassLoader->ExtClassLoader->AppClassLoader
类加载器之间的关系是:AppClassLoader的父加载器是ExtClassloader,
ExtClassLoader的父加载器为null,BootStrap ClassLoader的为顶级
类加载器。
双亲委派模式流程:(子加载器自己不会尝试加载类,它会先委派给父类,当父类
无法加载时才有子加载器自己来尝试加载类)
当需要查找一个class对象的时候,由于类加载机制只要加载过该类,就不需要去重新
加载,只需要查找缓存
1.查找缓存路径:查找自身加载器是否有缓存,没有就委派父类AppClassLoader->
查找AppClassLoader加载器是否有缓存,没有就委派父类ExtClassLoader->
查找ExtClassLoader加载器是否有缓存,没有则委托BootStrap ClassLoader
->查找BootStrap ClassLoader加载器是否有缓存,没有则开始加载(在任何一个
加载器中,该类已被加载的话,直接返回)
2.加载路径:BootStrap ClassLoader在核心库中加载,如果没有加载成果->
ExtClassLoader在lib/ext中加载,如果没有加载成果->AppClassLoader在当前
classpath中加载,如果没有加载成果->自定义加载器加载,如果没有加载成果
->抛出异常ClassNotFoundException
双亲委派机制的优点:
1.通过双亲委派机制,java自带的系统类一定是被java自带的类加载器加载的,
保证了系统的安全性(举例:假如不是双亲委派模式,由子加载器自己加载类,那么
黑客可以自己编写一个和系统类同名的类,如String,当自己编写的String类被加载
进来时,系统是极度不安全的)
2.如果是相同的类,使用不同的类加载器去加载,会在方法区保存两个不同的.class
文件(因为.class文件中保存了一个加载本类的类加载器的引用),并且在堆区创建
两个java.lang.class对象,这两个class对象不相同。有了这个前提后,java中有一些
核心类,假如使用自己的类加载器去加载的话,实例化后就会造成这些类之间不兼容
,并且一堆明明是相同类,但是因为类加载器不同而不同的类也浪费空间。所以
选择代理模式。

类加载器的命名空间
该类加载器和其所有父类加载器加载的类组成该类加载器的命名空间
1.命名空间中不会存在全限定类名相同的类
2.同一命名空间内,子类加载器加载的类可以访问父类加载器加载的类,但是父类加
载器加载的类却不可以访问子类加载器加载的类

类加载器也是类由谁来创建呢:
1.ExtClassLOader和AppClassLassLoader由BootStrap ClassLoaderL来创建,
而BootStrap ClassLoader是jvm的一部分,由C++编写,随着jvm的创建而创建。
自定义类加载器由AppClassLassLoader来创建。

链接阶段
1.验证:验证类数据信息是否符合jvm规范,是否是一个有效的字节码文件,验证
内容涵盖了类数据信息的格式验证,语义分析以及操作验证等。
格式验证:验证是否符合class文件规范
语义分析:检查一个被标记为final的类型是否包含子类,检查一个类中的final方法
是否被子类进行重写,确保父类和子类之间没有不兼容的一些方法声明
(比如方法签名相同,但方法的返回值不同)
操作验证:在操作数栈中的数据必须进行正确的操作,对常量池中的各种符号引用
执行验证(通常在解析阶段执行,检查是否通过富豪引用中描述的全限定名定位到
指定类型上,以及类成员信息的访问修饰符是否允许访问等)
2.准备阶段:为类中的所有静态变量分配内存空间,并设置初始值(数值型为0,类
类型为null,boolean类型为false ,char类型为空)实例变量不再此操作范围。

(未完)