Class文件结构

  • 魔数 4bits 确定该文件是否是可接受的Class文件(0xCAFEBABE)
  • 版本号 4bits 包括次版本号和主版本号
  • 常量池 包括字面量(文本字符串,声明为final的常量值)和符号引用(类和接口的全限定名,字段的名称和描述符,方法的名称和描述符)
  • 访问标志 2bits 标志识别类或者接口层次的访问信息,如类是否为public,是否为abstract,是否为final,是Class还是Interface。
  • 类索引 父索引与接口索引集合 用于确定这个类的继承关系
  • 字段表集合 包括用于描述接口或类中声明得变量,包括public private protected static final volatile transient synthetic(字段是否为编译器自动产生) enum,以及变量简要名称和类型描述符(基本类型,数组)。
  • 方法表集合 类似字段表集合,包括前缀,简要名称,类型描述符,不包含方法中的代码。
  • 属性表 存放多种属性,如方法中的代码存在Code属性中,操作栈深度最大值,exception等。

类加载机制

类加载的整个生命周期: 加载,验证,准备,解析,初始化,使用,卸载

对类初始化的情况

  • new关键字实例化对象,读取设置类的静态字段(非final修饰),调用一个类的静态方法
  • 反射调用
  • 初始化一个类时,若父类没有初始化,则先初始化父类
  • 虚拟机启动时,用户指定的主类
  • java.lang.invoke.MethodHandle的解析结果是一个静态方法,则需要先初始化方法对应的类

加载

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

验证

  • 文件格式验证:对Class文件进行格式校验。是否以魔数开头,主次版本号是否可处理,常量池中常量是否全支持...
  • 元数据验证:对字节码描述的信息进行语义分析。这个类是否有父类,父类是否不允许继承,字段是否与父类矛盾...
  • 字节码验证:对数据流和控制流进行分析。对方法体进行校验分析,如类型校验等。
  • 符号引用验证:对符号引用进行校验保证其可转换为直接引用。

准备

  • 为变量分配内存。(仅包含类变量,不包括实例变量)
  • 为变量设置初始值。(仅设置类型对应的默认值,不赋值)

解析

解析阶段虚拟机将常量池内的符号引用替换为直接引用。

符号引用用一组符号描述所引用的目标,使用时可以无歧义的定位到目标。

直接引用可以是直接指向目标的指针,相对偏移量,或能够间接定位到目标的句柄。不通虚拟机中翻译出的直接引用一般不同。

初始化

初始化是类加载过程中最后一步。初始化接端是执行类构造器<clinit>()方法的过程。该方法是编译器自动收集类中所有类变量的赋值动作和静态语块(static{})中的语句合并而成的,其收集顺序取决于源文件中的出现顺序。虚拟机会保证子类的<clinit>()执行前,父类的<clinit>()已经执行过,因此不需要显示的调用。多线程环境中,<clinit>()方法使用悲观锁阻塞,并保证只被运行一次。

类加载器

上述过程中,第一步加载中,通过一个类的全限定名来获取描述此类的二进制字节流这个机制放在Java虚拟机外部实现,实现这个动作的代码模块称为类加载器。任意一个类,都需要由它的加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器都拥有一个独立的类命名空间。两个类是否相等,只在这两个类是由同一个类加载器加载的前提下才有意义,否则必顶步等。(相等指equals()方法,instanceof关键字等)

双亲委派模型

从JVM角度,只存在两种不同的类加载器:启动类加载器,C++实现,JVM一部分;其他类加载器,Java实现,独立于类,继承java.lang.ClassLoader。

启动类加载器负责将\lib中JVM识别的类库加到JVM内存中(如名字为rt.jar),启动类加载器无法被Java程序直接引用,用户自定义加载器时,把加载请求委派给引导类加载器只需要使用null替换。

其他类加载器包括扩展类加载器和应用程序类加载器,前者负责加载\lib\ext目录中的类库,后者是ClassLoader::getSystemClassLoader()的返回值,负责加载用户类路径上指定的类库,没有自定义过类加载器,这个加载器就是程序中默认的加载器。

这些加载器的关系如图所示

双亲委派模式要求除了顶层的启动类加载器,其余的类加载器都应该有自己的父加载器。其工作过程中,如果一个类加载器收到了类加载的请求,它首先不回去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层级的加载器都是如此,因此所有的加载请求最终都应该传到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。该模式保证了Java程序中的稳定性,如,重写rt.jar类中的类,不会有编译错误,但无法被加载。

双亲委派模型不是强制性约束模型,由于它的某些缺陷(如基础类要调用回用户的代码),某些标准服务打破了它,如JNDI服务,用于对资源进行集中管理和查找,JNDI使用了线程上下文类加载器。Java中所有涉及SPI的加载动作都采用这种方式,如JDBC。另外,模块热部署也破坏了双亲委派模型。

Java基础:类文件结构及类加载的更多相关文章

  1. 深入理解java虚拟机【Java Class类文件结构】

    Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码 ...

  2. (转)《深入理解java虚拟机》学习笔记5——Java Class类文件结构

    Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码 ...

  3. 第31节:Java基础-类与对象

    前言 Java基础-类与对象,方法的重载,构造方法的重载,static关键字,main()方法,this关键字,包,访问权限,类的继承,继承性,方法的重写,super变量. 方法的重载:成员方法的重载 ...

  4. 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制

    第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...

  5. Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架

    类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...

  6. Class类文件结构、类加载机制以及字节码执行

    一.Class类文件结构 Class类文件严格按照顺序紧凑的排列,由无符号数和表构成,表是由多个无符号数或其他数据项构成的符合数据结构. Class类文件格式按如下顺序排列:   类型 名称 数量 u ...

  7. Java虚拟机-类文件结构

    目录 类文件结构 Class类文件的结构 魔数与Class文件的版本 常量池 访问标志 类索引.父类索引和接口索引集合 字段表集合 方法表集合 属性表集合 完整结构描述 实例 源码 Class文件 分 ...

  8. JAVA基础知识之JVM-——自定义类加载器

    JVM中除了根加载器之外其他加载器都是ClassLoader的子类实例, 可以通过扩展ClassLoader的子类,通过重写方法来实现自定义的类加载器. ClassLoader中有两个关键的方法如下, ...

  9. jvm虚拟机笔记<三> 类文件结构与类加载机制

    java虚拟机具有语言无关系,它只和“class文件“这种特定的二进制文件格式绑定. 不同语言的编译器将对应的程序编译成字节码文件(*.class),送给jvm执行. class文件本质上就是一张表, ...

随机推荐

  1. zabbix基本介绍

    来源是 觅安教育 大家有兴趣可以去哔哩哔哩搜搜. Open-falcon是由小米公司开源 比如windows,linux,unix,openBSD,AIX,solaris,Mac等操作系统,都可以安装 ...

  2. python代码统计

    代码统计 修改filename为文件夹or文件地址,然后统计所有python文件代码 import os import sys def count_code_lines(filename): res ...

  3. SSM + ehcache 异常

    异常如下: 十二月 26, 2017 1:24:44 下午 org.apache.jasper.servlet.TldScanner scanJars 信息: At least one JAR was ...

  4. Django基础(2)-如何安装特定版本的Django项目

    Django1.0版本和2.0版本的差异较大,这里jacky更常用的Django的1.9.8的版本,本小节jacky将给大家分享如何用Pycharm创建1.9.8版本的项目 (一)使用Pycharm配 ...

  5. hadoop错误记录部分总结

    错误记录与分析 错误1:java.net.BindException: Port in use: localhost:0 datanode节点启动时报错 日志信息如下: Exiting with st ...

  6. vue+element 表格formatter数据格式化并且插入html标签

    前言 vue中 element框架,其中表格组件,我既要行内数据格式化,又要插入html标签 一贯思维,二者不可兼得也 一.element 表格 数据格式化 demo <el-table-col ...

  7. Java hashCode与equals学习

    1.关于Object类的equals方法的特点 a) 自反性: x.equals(x) 应该返回true b) 对称性: x.equals(y)为true,那么y.equals(x) 也为true c ...

  8. tomcat的AJP(定向包协议)协议

    由于tomcat的html和图片解析功能相对其他服务器如apche等较弱,所以,一般都是集成起来使用,只有jsp和servlet服务交由tomcat处理,而tomcat和其他服务器的集成,就是通过aj ...

  9. js 跳转到 百度指定地址定位点

    js 跳转到 百度指定地址定位点 http://api.map.baidu.com/geocoder?address=北京市海淀区上地信息路9号奎科科技大厦&output=html&s ...

  10. 006-多线程-JUC线程池-并发测试程序

    一.java代码模拟并发 1.1.一次并发 单次并发测试 1.使用CountDownLatch 等待一个或多个线程一起执行 详细参看:007-多线程-锁-JUC锁-CountDownLatch-闭锁[ ...