[Class文件结构]1——概述

前言

众所周知,计算机只识别0和1,程序员写的c或c++程序最终都要经过编译、链接等步骤,将代码转换成0或1的二进制格式才能被计算机执行。由于依赖平台,导致c语音中基础数据类型在各平台上所占的字节数都不相同,其它细节也有不同。

Java不一样,Java在诞生之初就宣称“write once,run anywhere”,它选择了与操作系统和机器指令集无关的、平台中立的格式作为程序编译后的存储格式。

实现语言无关性的基础就是虚拟机和字节码存储格式,使用Java编译器可以把Java代码编译为存储字节码的Class文件,使用JRuby等的编译器一样可以把代码文件编译成Class文件,虚拟机并不关心Class文件的来源,只要它符合Class文件就有的结构就可以在Java虚拟机中运行。

Class类文件的结构

解析学习Class类文件的结构,是了解虚拟机的重要基础之一,有助于学习虚拟机如何加载并执行class文件。

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符。

Class文件采用一种类似C语言结构体的伪结构来存储,这种伪结构中只有两种数据类型:无符号数和表。

无符号数基于基本的数据类型,以u1,u2,u4,u8来分别代表1个字节、2个字节、4个字节、8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或按照UTF-8编码构成的字符串值。

无论是无符号数还是表,当需要描述同一类型但数量不定的多个数据时,经常会使用一个前置的容量计数器加若干个连续的数据项的形式,这时候称这一系列连续的某一类型的数据为某一类型的集合。

注意:Class文件不像xml,它没有分隔符,而且它的顺序都是严格定义的。

Java代码中包含成员变量,方法,变量还定义了访问权限,方法还有参数、返回值,方法中的逻辑(比如说int型数据相加)是否会被存储成一个个指令,Class文件会如何描述这些东西呢?

示例代码

以如下代码为示例,查看编译后的Class文件。

package org.fenixsoft.clazz;

public class TestClass {

    private int m;

    public int inc(){
        return m + 1;
    }
}

Class文件是字节码文件,需要使用16进制编辑器查看,本文中选用 WinHex,打开Class文件后整体如下:

另外Class文件可以使用javap工具查看,指令如下:javap -verbose class文件路径

魔数与Class文件版本

每个Class文件的头4个字节称为魔数,它的唯一作用是用于确定这个文件是否为Class文件。查看上单节的Class文件格式图,魔数正好也是由一个u4类型表示。

Class文件的魔数为 cafebabe(咖啡宝贝?)。

魔数之后即是次版本号和主版本号,二者均由一个u2表示。

本例中次版本号为0,主版本号为51(33是16进制数,换成10进制就是51),即为Java 1.7。注意高版本的JDK能向下兼容,但无法运行以后版本的Class文件,那么本例中的Class文件只能被JDK 1.7及以上运行。

常量池

主版本号后边就是常量池了,常量池中的所有项目类型为:

使用javap -verbose 查看Class文件,查看常量池部分

常量池中存放两大类常量:字面量和符号引用。字面量,如字符串、被声明为final的常量值等。而符号引用(符号引用属于编译原理方面的概念)包括了下面三类常量:

  • 类和接口的全限定名
  • 字段的名称和描述符
  • 方法的名称和描述符

和Java代码中的常量不一致,常量池中并不是只会存储final类型的数据,不是常量也会被存储,比如示例代码中的m,另外符号引用也并不是代码中所说的引用类型,除了类和接口,它还包含字段和方法。

虚拟机在加载Class文件时进行动态连接,也就是说Class文件并不会保存各个方法和字段的最终内存布局信息,当虚拟机运行时,需要从常量池中获取对应的符号引用,在运行时解析并翻译到具体的内存地址当中。

常量池是最繁琐的数据了,因为常量池中所包含的11种类型都有自己的结构。一般是由一位u1指定类型,再加上数据长度(一般是u2),再加上数据具体值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,176评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,928评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 171,252评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,700评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,717评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,231评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,608评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,572评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,117评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,137评论 3 344
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,280评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,908评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,597评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,067评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,202评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,784评论 3 380
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,308评论 2 365

推荐阅读更多精彩内容

  • 字节码查看工具:WinHex 前言 Java虚拟机实现语言无关性的基石就是Class文件Java虚拟机提供的语言无...
    zlcook阅读 7,144评论 4 18
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,680评论 18 399
  • ---剽悍新江湖100天成长目标 四期五连三排52号郭艳 行动营22天的经历让我开拓了视野,明白了什么是真正的学习...
    燕灵湾阅读 405评论 1 1
  • 初春,凉意依旧直袭人心。弯月寒光微微,草坪上似乎有潮意慢慢升腾,我打开随身带来的老白干,任由六十七度的烈酒热辣辣地...
    骑鲸_阅读 2,849评论 31 39
  • 此时此刻,我已经心情平复了许多,而就在刚才,我还连饭都吃不下!我的感受是压抑愤怒,和强大的委屈。到马上进入到幼儿园...
    崔峰媳妇孙小莹阅读 222评论 2 1