class文件概述

将java代码编译后会产生class文件,并且一个clas文件会对应唯一一个java类或者接口。下面对一个通过一个简单的例子来简述一下class文件的结构。

java代码

public class JavaMethodAreaOOM{
    String str = "abc";
    int i = 1;
    static String str1 = "123";

    public static void main(String[] args) {
        int b = 1;
    }

    public void test(){
        System.out.println(str1);
    }
}

在java代码中我们定义了一些属性和方法。下面是编译生成的字节码文件

字节码文件

我们看到,源代码不长,但是生成的字节码文件内容却很多,下面就针对上面的例子进行分析。

字节码分析

  在字节码文件中只存储了两种类型的数据,一种是无符号数(u1,u2,u4,u8,u1表示一个字节,u2表示两个字节...),一种是表(表其实就是无符号的集合,不过表中的数据之间是有联系的,而且表中还可以存放表,表一般以_info结尾)。 字节码文件中数据存放顺序是按照下面表中的顺序存放的,比如文件的开始位置会存放4个字节的数据,我们称之为magic。所以,在进行字节码分析时,我们可以参考下面的表进行对比分析。

 

magic(u4)的翻译是魔术,但是这里是魔数。这个魔数的作用就是文件标识,用来标识这是一个字节码文件可以被JVM加载运行。查看字节码开始的4个字节,我们会发现是cafebabe。所有的字节码文件开始都是这样的。

minor_version(u2)紧跟着魔数有两个字节(0000)表示次版本号,次版本一般是JDK的某个分支如JDK 1.1有个分支为JDK1.1.8,那么此版本号就为0x0003。这个次版本号不太重要。

major_version(u2)接下来的两个字节(0033)表示主版本号,这个主版本号很重要。我们经常会看到用低版本的java编译器编译出来的class文件无法在高版本的虚拟机上运行就是因为JVM会查看这个值。0x0033的十进制是51表示这个class文件只能在JDK1.7以上的虚拟机中运行(版本号对应的JDK这里可自行百度)。

constant_pool_count(u2):记录常量池中常量的个数,002C的十进制为44,表示在常量池中有44个常量。因为常量的池的大小不固定,如果没有这个数的话JVM在加载常量池不知道需要申请多大的空间才合适。

constant_pool(cp_info):这就是我们所谓的常量池,我们看到常量池使用表来表示的。其原因就是常量池中存放的大量的数据,我们用最大的基本类型u8也只能表示8个字节,所以只能用表来描述这段区域了。下面就是常量池中能放的内容:字面量和符号引用。字面量就是我们定义的字符串,final常量等,而符号引用包括类和接口的全限定名,方法名和描述符,字段名和描述符。

  对常量池中存放的常量都是以表的方式来描述的。在每个表的开始位置是个tag(u1),用来表示该常量是什么。我们可以对应下面的表来分析常量池中的数据。

  我们开始对常量池进行分析

  第一个常量0a00 0a00 1a,我们查表发现。OA是一个表示常量池中第一个常量是方法的符号引用,紧跟着我们看到000a 和001a。通过查表我们发现这是两个索引。第一个索引指向的是一个CONSTANT_Class_info这种表的数据位置,第二个索引指向CONSTANT_NameAndTyep_info这种表数据位置。简单来说,000A指向常量池中第10个常量,而001a指向第26个常量。下面是第26个常量中放的内容。我们查表可以得到07表示一个对类描述的表,0025又是一个索引,这个索引指向第37个常量。

  第二个常量08 001b,通过查表(08)我们发现,第二个常量是字符串类型。他的第二个索引是001b(27),指向第27个常量。至于第27个常量中具体放的什么,这里就不做分析了。

  总结一下,我们观察了常量池中的前两个常量,第一个是方法,第二个是字符串。但是我们发现方法处并未显示有具体的方法,字符串处并未看到具体的字符,放到全是索引。这就是class文件的一个特点,先说有这个东西,具体是是什么请通过后面的索引去查找。下面我们借助java中的工具看看常量池中内容。

通过工具我们可以直观的看到看到常量池中内容了。

  我们看到第一个常量是方法,这和我们分析的一样。常量中的数据是索引#10和#26。在#10处我们看到是一个Class常量,而Class中有个索引是#37.#37处的常量这里没有显示,但是通过后面的注释可以看到#37处放的是java/lang/Object字符串,存储类型是UTF8,表示类名。通过一步步查找我们可以知道,方法中的第一个常量是类名,表示这个方法属于哪个类,而“<init>”表明该方法的的名称,()V表示该方法的无参且返回值为void。那这个方法具体对应代码中的那个方法呢?其实就是我们从父类继承来的无参构造器。

  第二个常量是String类型,存储的数据是索引#27。而第27个常量处放的是Utf8类型,而内容为abc。这样就和我们的代码对应起来了,但是还一点就是这个字符串常量是被赋值给一个str属性的,这个str在哪里呢?

  第三个常量是Fieldref,我们看到它里面存的还是索引,而索引中的内容是UTF8类型的字符串。字符串的内容是 JavaMethodAreaOOM和str:Ljava/lang/String;这表示这个属性属于JavaMethodAreaOOM类的属性,而这个属性的类型是String类型。

  第四个常量也是Fieldref,这就是我代码中的int类型了。索引中存储的是JavaMethodAreaOOM和i:I,前者表示所属类,后者是名字和类型。i就是变量名而I就是int类型了。

常量池总结

量池中大的分类就是字面的量和符号引用。细化后就是字符串常量,索引值,类名,方法名,属性名,属性的类型,方法的参数,方法的返回值。而方法体以及一些其他属性的初始化操作(int=1)会放在class文件的代码中进行执行。

常量池之后是访问标志(两个字节)了,这个访问标志了这个类的访问信息。包括是接口还是类,是否为public。下面是对访问标志的描述。

时间: 2024-08-03 17:56:26

class文件概述的相关文章

Java类编译后Class文件概述(上)

一.Class文件 注意:每一个Class 文件都对应着唯一一个类或接口的定义信息,但是相对地,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过类加载器直接生成). 二.class文件的文件结构 class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构只有两种数据类型:无符号数和表. class文件的结构描述 ClassFile { u4 magic; <span style="white-space:pre"> </span>//4位

计算机程序的思维逻辑 (56) - 文件概述

我们在日常电脑操作中,接触和处理最多的,除了上网,大概就是各种各样的文件了,从本节开始,我们就来探讨文件处理,本节主要介绍文件有关的一些基本概念和常识,Java中处理文件的基本思路和类结构,以及接来下章节的安排思路. 基本概念和常识 二进制思维 为了透彻理解文件,我们首先要有一个二进制思维.所有文件,不论是可执行文件.图片文件.视频文件.Word文件.压缩文件.txt文件,都没什么可神秘的,它们都是以0和1的二进制形式保存的.我们所看到的图片.视频.文本,都是应用程序对这些二进制的解析结果. 作

VMware vsphere vcenter 服务器日志文件概述

此文档概述了vcenter server 和vcenter appliance服务器日志文件简要概述 访问访问: 1.可以通过vsphere client 和 web client来查看 2.可以再vcenter服务器日志目录查看 日志位置: VMware vCenter Server 6.0:%ALLUSERSPROFILE%\VMWare\vCenterServer\logs folder. VMware vCenter Server Appliance 6.0 : /var/log/vmw

《PNG文件格式》(一)PNG文件概述

欢迎查看系列博客: <PNG文件格式>(一)PNG文件概述(本篇) <PNG文件格式>(二)PNG文件格式分析 <PNG文件格式>(三)PNG文件实例剖析 摘自: 中文PNG格式说明:dev.gameres.com PNG文件格式白皮书:www.w3.org LZ77算法的JAVA实现:jazzlib.sourceforge.net LZ77算法的JAVA实现,包括J2ME版本:www.jcraft.com ===============================

【JAVA 文件概述】

一.概述 使用此类的原因: 该类将文件或者文件夹封装成对象.方便对文件与文件夹的属性信息进行操作.File对象作为参数传递给流的构造函数.要求:使用File类的常用方法. windows平台下,目录分隔符是\,而linux下是/,在字符串中,\符号需要使用\\,第一个\起转义作用.该分隔符可以使用System.getProperty("file.separator");得到. 二.常用方法. 1.构造方法. 构造方法摘要 File(File parent, String child)

VMware vsphere esxi 服务器日志文件概述

此文档概述esxi 及 vcenter服务器相关的log日志文件清单及每个日志文件内容 访问日志文件: 1.可以通过直接登录控制台用户界面(DCUI)查看 2.可以使用ssh 连接esxi服务器查看(需要在esxi服务器上启动ssh服务) 3.可以通过https://esxi主机ip 来查看 日志文件路径:     /var/log SXi 5.1主机的日志文件 日志ESXi 5.1主机分组根据源组件: /var/log/auth.log :ESXi壳身份验证成功和失败. /var/log/dh

一、MP3文件概述

一.概述 MP3 文件是由帧(frame)构成的,帧是 MP3 文件最小的组成单位.MP3 的全称应为 MPEG1 Layer-3 音频文件,MPEG(Moving Picture Experts Group)在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG音频文件是 MPEG1 标准中的声音部分,也叫 MPEG 音频层,它根据压缩质量和编码复杂程度划分为三层,即Layer-1.Layer2.Layer3,且分别对应 MP1.MP2.MP3 这三种声音文件,并根据不同的用途,使用不同层

launch文件概述---1

摘要: 原创博客:转载请表明出处:http://www.cnblogs.com/zxouxuewei/ 资源链接:http://wenku.baidu.com/link?url=PhyN3C6ghqovJ0qtg8dnTEPEku6WFDnB2dOeMqfErVLx8hB4MksBUULiNLlvjwWtsgDRTcizA2jCFhCjdgu0rRTfsq2mUtiRr5GKUtfYtMi pdf转world:http://www.convertpdftoword.net/ 1.计算次序rosl

Java类编译后Class文件概述(下)

具体的实例 Java文件 package com.weixuan.test; public class MyTest { private int age; private String name; public int getAge() { return age; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public void setName(String