第6章 类文件结构

Posted ashoftime

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第6章 类文件结构相关的知识,希望对你有一定的参考价值。

6.1 概述

  计算机只认识0和1,传统的语言直接交给操作系统去执行,所以他们不能像Java一样,一次编译到处运行。Java编译后的代码是由虚拟机执行,编译后的结果是平台中立的格式。

6.2 无关性的基石

  各种平台下Java编译后的格式都是一样的,所以称为平台中立的,这个格式就是字节码(Byte Code)。Java虚拟机只认识字节码即class文件,所以虚拟机也可以执行别的语言,只要这些语言编译后的代码是class文件。

6.3 Class类文件的结构

  主要介绍class文件的结构,以jdk1.4为主线。

  class文件是什么?是一组二进制字节流,其格式有着严格的要求必须以8字节为单位进行排列。如果需要占有的字节大于8字节就需要按照大端的方式进行分割,最高位字节在最低位。这个与x86处理器相反,x86采用最低位字节在地址最低位。这个字节码对格式的要求非常严格,中间没有分隔符。没有分隔符怎么能确定一个字段哪里开头哪里结尾呢?所以class的结构对顺序、数量都是被严格规定的。

  class文件的结构类似于c语言里的结构体,由两种数据结构组成,一种是无符号数,一种是表。无符号数用来存储基本的数据类型的内容。表是一种复合的数据结构,由多个无符号数和别的表组成。

  技术分享图片

6.3.1 魔数与class文件版本

  class文件开头是魔数,是指用来判断这个二进制文件是不是class文件的。我们平时看一个文件的类型是从扩展名来判断,这其实不太安全,因为扩展名是可以改的。java虚拟机根据一个二进制文件的头4个字节的内容是不是指定的内容来判断是不是class文件。

  跟着魔数后面是class文件的版本的判断,用来判断class文件的版本与虚拟机的版本是不是兼容。

6.3.2 常量池

  紧接着魔数和class文件版本的就是常量池了。为什么要有常量池呢?把所有的常量放在一个池子里,如果一段java里出现了两个同样的字符串,那么就没有必要加载两次,直接再次引用即可,因为是常量,不会改变。具体而言常量池里有两大类的数据:1、字面量(Literal),符合我们对常量池的一般认知,放的是java里的字符串、final修饰的变量等待。这部分内容肯定是常量。2、符号引用。从常量的角度而言,这部分也是不可改变的。有类或者接口的全限定名称,一个字段的名称和描述符,一个方法的字段和描述符。由于java在编译的时候没有链接这一步,引用别的方法都不能直接转换成真实的地址,只有在运行的时候才能被翻译成真正的入口地址,所以这部分内容要在内存里保存下来。

  常量池第一个字段是保存了常量池里有多少的个常量,索引从1开始。

6.3.3 访问标志

  用来标记这段class对应的java代码是不是一个类,是不是一个接口,是不是抽象的等等信息。  

以上是关于第6章 类文件结构的主要内容,如果未能解决你的问题,请参考以下文章

6.1 QDir目录操作

类文件结构

类文件结构

玩转数据结构:第7章 集合和映射

C#第3章学习要点--常用类和结构的用法

跟着腾讯T4学架构:微服务+MySQL+Nginx+Redis+容器化+虚拟机