只是做笔记,列上自己觉得需要记住的(闲杂人等请勿较真)
类加载时机
遇到new,getstatic,putstatic或者invokestatic这四条字节码指令时
使用java.lang.reflect的方法对类进行反射调用的时候
当初始化一个类的时候,如果发现其父类还没有进行初始化,先初始化父类
当虚拟机启动时,用户需要指定一个要执行的主类,(main)虚拟机会先初始化这个类
当使用jdk1.7动态语言支持是,如果java.lang.invoke.MethodHandle实例最后的解析结果REF_getstatic的方法句柄,并且这个方法句柄所对应的的类没有进行初始化,则初始化这个类
类加载过程
1.加载
2.验证
3.准备
4. 解析
类和接口解析,字段解析,类方法解析,接口方法解析
5.初始化
是类加载的最后一步,这时才开始执行java程序代码
类:父类的<cinit>()先执行,弗雷中定义的静态语句块要优先于子类的变量赋值操作
接口:执行接口的<cinit>()方法不需要执行父接口的<cinit>()方法,只有当父类接口中定义的变量使用时,父接口才会初始化<cinit>(),另外接口的实现类在初始化时也一样不会执行接口的<cinit>()方法
6.类加载器
所谓相等,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则即使这两个类源于同一个class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个类一定不相等
种类:启动类加载器,扩展类加载器,应用程序加载器,自定义加载器
双亲委派机制过程:如果一个类加载器收到类加载请求,他首先不会尝试自己去加载这个类,而是把请求委派给父类加载器去完成,每一层都是如此,因此所有加载请求最终都会汇总到顶层的启动类加载器,如果父类加载器反馈自己无法完成这个请求(它的搜索范围没有找到所需类)时,子类才会尝试自己加载
破坏双亲:
向上兼容
有线程上下文加载器(spi的加载动作JNDI,JDBC,JCE等)
由于用户对程序动态性的追求而导致的(代码热替换,模块热部署),例如鼠标插上就可以用而不需要重启机器