简述
class文件是什么?稍微接触过java的同学都会说:就是java源文件编译后的.class文件。这句话虽然对,但是不够准确。其他语言,例如scala,jruby等,都可以编译出class文件。class文件是能被jvm识别和运行的一种文件格式。它是八位的二进制流文件。今天就跟大家一起学习class文件的格式
整体结构
用ultraedit等工具打开class文件,看到的都是二进制。首先要了解哪几位代表什么标志?这里用u1,u2,u4,u8,代表属性占用多少个字节。
格式,如下
类型 名称 数量
u4 magic 1
u2 minor_version 1
u2 major_version 1
u2 constant_pool_count 1
cp_info constant_pool constant_pool_count-1
u2 access_flags 1
u2 this_class 1
u2 super_class 1
u2 interfaces_count 1
u2 interfaces interface_count
u2 fields_count 1
field_info fields fields_count
u2 methods_count 1
method_info methods methods_count
u2 attributes_count 1
attributes_inof attributes attributes_count
详细
看了上面的大体介绍,明白了class文件的基本结构后,我们就逐一来介绍各个部分。
1.magic
前四个字节 0xCAFEBABE,就是代表该文件格式是class文件了。出于安全考虑,class文件不是以文件后缀名来识别
2.minor_version 和 major_version
jvm只能处理低于或者等于它版本后的class文件。所以class文件首先要定义自己的版本,才能让jvm判断能否执行。版本号的描述一般都是 major_version.minor_version。各个版本号代表的数值可以去查看jvm说明书
3.constant_pool
常量池,里面包含了类和接口相关的常量,比如final变量值、类名、方法名等。接下来定义方法等信息时,就给一个索引去常量池寻找相关的信息。这个索引是从1开始的。为什么不是0开始?其实是有的,只不过被当做特殊用途了。所以constant_pool_count是将索引0也计入在内。每个常量值都有一个u1大小的标志。如下:
入口类型 标志值 描述
CONSTANT_Utf8 1 UTF-8编码的Unicode字符串
CONSTANT_Integer 3 int类型字面量
CONSTANT_Float 4 float类型字面值
CONSTANT_Long 5 long类型字面量
CONSTANT_Double 6 double类型字面量
CONSTANT_Class 7 对一个类或者接口的符号引用
CONSTANT_String 8 String类型字面量
CONSTANT_Fieldref 9 对一个字段的符号引用
CONSTANT_Methodref 10 对一个类中声明的方法的符号引用
CONSTANT_InterfaceMethodRef 11 对一个接口中声明的方法的符号引用
CONSTANT_NameAndType 12 对一小字段或者发放的部分符号引用
常量池中包括了:字面量;类和接口的全限定名;字段的名称和描述符;方法的名称和描述符。字段飞描述符就是字段类型的字符串。方法的描述符是方法返回值和参数的数量,顺利和类型的描述。jvm只是从常量池中获得符号引用,然后在运行时解析引用项的实际地址。
4.access_flags
顾名思义就是类或者接口的访问修饰符,例如public abstract等。每个访问修饰符用一位二进制位来表示。access_flags就是所有的访问修饰符“与”关系。//todo 访问修饰符的定义
5.this_class
类的基本信息。包括两个字节,是常量池的一个CONSTANT_Class_info表的索引。该表结构包括两部分:tag和name_index。tag值等于该索引值。通过name_index,我们又可以在常量池中找到一个对应的CONSTANT_Utf8_info表。Utf8表结构包括三部分:tag(等于utf8表的索引值);length和byte(字符串内容)
6.super_class
父类的相关信息。格式跟this_class一样。每个对象只有一个父类(单继承)。而object类的super_class为0
7.interfaces_count和interface
所实现的接口的相关信息。每个接口都由一个索引指向常量池中的一个CONSTANT_Class_info
8.field_count和fields
字段的相关信息。每个字段都由一个索引指向常量池的一个field_info。这里不会出现父类的field。但可能出现一些代码中没有定义的字段,是编译器额外添加的。例如,内部类中,会有一个外部类的实例
9.methods_count和methods
关于方法的相关信息,每个方法都有一个索引指向常量池的method_info表
10.attributes_count和attributes
类或接口所定义的属性的基本信息。每个属性都由一个索引指向常量池的attribute_info。属性在很多地方都出现,比如在field_info中出现描述与字段相关的属性信息。在顶层ClassFile中有两种属性-SourceCode和InnerClass
11.几个常用到的概念
全限定名-把类的全名用.替换成/
简单名称-方法或者字段的名称,不包括任何的修饰符
描述符号
比较复杂.先来看类型的定义.B-byte,C-char,D-double,F-float,I-int,J-long,S-short,Z-boolean,V-void,L对象全限定名-对象类型.
描述数组,用前置的”[“来表示,有几维就加多少个”[“.
字段描述符=数组描述符+类型描述符
方法描述符=左括号+参数描述符(按定义的顺序)+右括号+返回值描述符
总结:
跟大家一起稍微了解了class文件的结构,明白了它的大概组织结构。篇幅有限,本来应该找个最简单的helloworld程序的字节码来一一说明的。详细例子,大家可以参考以下书籍
参考资料
1.深入java虚拟机
2.深入理解java虚拟机
更多关于jvm的内容欢迎访问 www.iamcoding.com
分享到:
相关推荐
### JVM学习笔记(一) #### 一、JVM概述与工具使用 JVM(Java Virtual Machine)是Java语言的核心组成部分之一,它为Java程序提供了一个跨平台的运行环境。本篇学习笔记主要介绍如何利用一系列工具来查看和监控JVM...
这个“java之jvm学习笔记五(实践写自己的类装载器)”很可能是对这一主题的详细探讨。 类装载器在Java中的主要职责是动态加载类到JVM中。Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、...
### JVM学习笔记 #### JVM内存模型 (JMM) JVM内存模型主要分为以下几个部分: - **Java堆**:这是所有线程共享的一块区域,在虚拟机启动时创建。主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。 - *...
本篇JVM学习笔记主要涵盖了以下几个核心知识点: 1. **运行时数据区**: - **程序计数器**:记录当前线程执行的字节码的行号,用于线程恢复执行时跳转到正确位置。 - **Java虚拟机栈**:每个方法执行时创建的栈帧...
### JVM中篇笔记知识点 #### 一、Class 文件结构 ##### 1. 概述 - **字节码文件的跨平台性** - Java 的跨平台性体现在 "Write Once, Run Anywhere" (WORA),即一次编写,到处运行。Java 语言编写的源代码在编译...
源码编译由Java源码编译器完成,这个过程包括了源码的分析、输入到符号表、注解处理和语义分析,最终生成包含结构信息、元数据和方法信息的.class文件。执行阶段则是由JVM执行引擎解析字节码并执行。这一过程涉及到...
### JVM学习笔记核心知识点整理 #### 一、引言与背景 随着软件开发技术的不断发展,Java作为一种广泛应用的编程语言,其背后的核心技术——Java虚拟机(JVM)的重要性日益凸显。掌握JVM不仅可以帮助开发者更好地理解...
这篇学习笔记主要探讨了Class文件的结构、内容和重要特性。 首先,Class文件是一种语言独立的存储格式,不仅用于Java,也可以支持其他如Scala等JVM为基础的语言。它由字节码构成,这种格式允许JVM执行不同语言编译...
《JVM学习笔记》 Java虚拟机(JVM)是Java平台的核心组成部分,它负责运行所有的Java应用程序。这篇笔记将深入探讨JVM的工作原理、内存管理、类加载机制以及优化策略,帮助读者全面理解JVM并提升Java程序的性能。 ...
在每个`.class`文件的开头都有一个魔数(Magic Number),其值为`0xCAFEBABE`,用来识别文件格式。紧接着是`minor_version`和`major_version`字段,它们分别表示次版本号和主版本号,用于标识字节码对应的Java版本。...
今天,我们要讨论的是 JVM 的笔记,这个笔记包括了 JVM 的基本结构、类加载机制、类文件格式等内容。 首先,让我们来看一下 JVM 的基本结构。JVM 可以分为三个部分:CLASS LOADER、RUN TIME DATA AREA 和 EXECUTION...
其中,加载是找到类的.class文件并读入内存;验证确保字节码的正确性;准备为类的静态变量分配内存并初始化为默认值;解析将符号引用转换为直接引用;初始化执行类的初始化方法。了解这个过程有助于我们理解和控制类...
【Java分布式应用学习笔记-谈JVM】 在Java分布式应用中,JVM(Java虚拟机)扮演着至关重要的角色。虽然有些人可能认为分布式系统与JVM的关系并不密切,但事实上,尤其是在大型分布式环境,如云计算服务平台,对Java...
加载是找到.class文件并读入内存;验证确保字节码的正确性,防止恶意代码;准备阶段为静态变量分配内存,并设置默认初始值;解析将符号引用转换为直接引用;初始化执行类构造器。 二、内存管理 JVM内存主要分为堆...
JVM的类加载器(ClassLoader)负责将编译后的`.class`文件加载到内存中,为程序执行做好准备。当类被加载时,JVM会在内存的运行时数据区的方法区内存储类的信息,并在堆中创建一个`java.lang.Class`对象来封装这些...
### 深入Java虚拟机JVM类加载学习笔记 #### 一、Classloader机制解析 在Java虚拟机(JVM)中,类加载器(ClassLoader)是负责将类的`.class`文件加载到内存中的重要组件。理解类加载器的工作原理对于深入掌握JVM以及...
1. **类加载机制**:JVM通过类加载器(ClassLoader)将字节码文件(.class)转换成运行时的类。类加载分为加载、验证、准备、解析和初始化五个阶段,每个阶段都有其特定的任务和目的,如确保类的正确性和内存分配。 ...