前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Java类加载-加载

Java类加载-加载

作者头像
shysh95
发布2021-02-25 10:59:27
发布2021-02-25 10:59:27
1.3K0
举报
文章被收录于专栏:shysh95shysh95

我们已经将整个Class的构成讲述完了,不清楚的同学可以看一下关于Class文件的介绍,但是空有Class并没有什么用,在Class中的各种描述信息都需要被加载到虚拟机以后才能运行使用。

什么是类加载

虚拟机把描述类的数据从Class(Class文件或者网络或者其他地方,其实都是一串二进制流)加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。这就是虚拟机的类加载。

类加载概念

上图是类加载和卸载的整个过程示意图,其中验证、准备、解析统称为连接阶段。

加载、验证、准备、初始化和卸载这5个阶段开始的顺序是固定的,但是解析阶段在某些情况下可以在初始化以后再进行。

JVM并没有对什么时候开启加载阶段进行强制约束,但是对于初始化阶段严格规定了有且只有5种情况必须立即对类进行初始化

  • 遇到new(new关键字实例化对象)、getstatic(读取一个类的静态字段(被final修饰、在编译期就把结果存入常量池的静态字段除外))、putstatic(设置一个静态字段)或invokestatic(调用静态方法)这4条指令时,如果类没有进行初始化,则必须先触发其初始化。
  • 使用java.lang.reflect包的方法进行反射调用的时候,如果类没有初始化,则必须先初始化
  • 初始化一个类的时候,如果父类没有被初始化(只有类的父类,接口的父类不会),则需要先初始化父类
  • JVM启动时首先初始化主类
  • 如果一个java.lang.invoke.MethodHandle实例的最后解析结果是REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,如果方法句柄所对应的类没有进行过初始化,则触发其初始化。

类加载-加载阶段

加载是类加载的第一个阶段,加载阶段的主要目标是:

  • 通过一个类的全限定名来获取定义此类的二进制字节流
  • 将字节流的静态信息结构转换为方法区(元数据区)的运行时数据结构
  • 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区(元数据区)这个类的各种数据的访问入口

二进制字节流的来源可以是(但不仅仅是):

  • Class文件
  • Zip包(也就是我们经常使用的JAR包、WAR包)
  • 网络
  • 其他文件,例如JSP
  • 数据库中读取(将二进制字节流的内容存储到数据库中)

除了上述五种二进制字节流,我们甚至可以在程序运行期间动态生成二进制字节流(动态代理技术)。

非数组类的加载需要通过类加载器实现,既可以使用系统的提供的引导类加载,也可以使用用户自定义的类加载器去完成,关于类加载器后续我会单独写一篇文章来介绍,并且实现我们自己的一个类加载器。

对于数组类来说,数组类是由Java虚拟机直接创建的,但是数组中的元素类型需要通过类加载器加载。数组类的可见性与数组中元素的可见性一致,如果元素不是引用类型,数组类的可见性将默认为public。

本期类加载的加载阶段就介绍到这,下期我们会讲解类加载的连接阶段,我们下期再见!!!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员修炼笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档