实例分析Java【4887王中王鉄算盘奖结果】,一文让

来源:http://www.smjxgs.com 作者:王中王鉄算盘 人气:83 发布时间:2019-10-05
摘要:参照链接:一文让您领会Java字节码 想必你写了看不完行的代码,只怕你能极度溜的行使高端语言,可是你不一定通晓那多少个高档语言的实践进度。例如大行其道的Java。 class文件是指

参照链接:一文让您领会Java字节码

想必你写了看不完行的代码,只怕你能极度溜的行使高端语言,可是你不一定通晓那多少个高档语言的实践进度。例如大行其道的Java。

class文件是指以.class为文 件后缀的Java虚构机可装载文件。无论该class文件是在linux上进展编写翻译的,如故在windows情形下编写翻译的,无论虚构机是在何种平台下降成和平运动作的,class文件使得Java设想机能够正确的读取、解释全部的class文件。 在分析和钻研class文件在此以前,先建议有部分标题:

Java字节码

Java称得上是一门“叁回编写翻译四处运转”的语言,可是大家对那句话的知道深度又有多少啊?从大家写的java文件到通过编写翻译器编写翻译成java字节码文件(也正是.class文件),那几个进程是java编写翻译进度;而大家的java设想机实行的正是字节码文件。不论该字节码文件来自何地,由哪一类编写翻译器编写翻译,乃至是手写字节码文件,只要顺应java设想机的正统,那么它就能够实施该字节码文件。那么本文首要讲讲java字节码文件有关文化。接下来大家由此实际的德姆o来浓厚精通:

1.类/接口(class文件也大概定义的是接口,所以依旧不要掌握为类公事为好)内有何内容?

Java虚拟机字节码指令

1 首先大家来写一个java源文件

4887王中王鉄算盘奖结果 1

javasrc.png

地点是大家写的三个java程序,很简短,只有五个成员变量a以及多个格局testMethod() 。

2.上述内容分别保存在class文件的如什么地方方?

Java堪称是一门“三回编写翻译到处运维”的语言,但是大家对那句话的掌握深度又有微微吧?从大家写的java文件到通过编写翻译器编写翻译成java字节码文件(也等于.class文件),那几个历程是java编写翻译进度;而大家的java虚构机奉行的正是字节码文件。不论该字节码文件来自哪个地方,由哪个种类编写翻译器编译,乃至是手写字节码文件,只要顺应java设想机的正儿八经,那么它就能够实践该字节码文件。

2 接下去大家用javac命令可能ide工具将该java源文件编写翻译成java字节码文件。

4887王中王鉄算盘奖结果 2

demo.png

上海教室是编译好的字节码文件,大家得以见到一批16进制的字节。借令你使用IDE去开拓,只怕见到的是曾经被反编写翻译的大家所熟稔的java代码,而那才是正面包车型地铁字节码,那也是大家前日亟需讲的内容首要。

想必你会对如此一批字节码感觉头痛,可是没什么,我们逐步试着您看懂它,或者有分化样的收获。在起来在此以前我们先来看一张图

4887王中王鉄算盘奖结果 3

java_byte.jpeg

那张图是一张java字节码的总览图,大家也正是坚守地方的次第来对字节码实行解读的。一共含有10某个,满含魔数,版本号,常量池等等,接下去大家依据顺序一步一步解读。

3.那一个剧情在加载进度中又何以被读取和深入分析?

字节码是Java程序的中等表示,就好比汇编是C或C 程序的中档表示。字节码是Java文件通过javac编写翻译器发生的(也正是.class文件)。程序中的字节码,不管是运作时JIT依旧HotSpot,字节码都以你程序大小和试行进程的入眼的一局地。注意,你持有的字节码越来越多,.class文件就越大,JIT或HotSpot运营时也就必要编译越来越多的代码。

3.1 魔数

从地点的总览图中大家精通前4个字节表示的是魔数,对应我们德姆o的是 0XCAFE BABE。什么是魔数?魔数是用来区分文件类型的一种标识,平日都以用文件的前几个字节来代表。比方0XCAFE BABE代表的是class文件,那么有人会问,文件类型能够透过文件名后缀来判别啊?是的,然而文件名是能够修改的(满含后缀),那么为了确认保证文件的安全性,讲文件类型写在文书之中来确认保障不被篡改。
从java的字节码文件类型我们看看,CAFE BABE翻译过来是咖啡宝物之意,然后再看看javaLogo。

4887王中王鉄算盘奖结果 4

java_icon.png

CAFE BABE = 咖啡。

4.这么些剧情加载后又会被解析成为何的数据结构保存在设想机中?

4887王中王鉄算盘奖结果 5java字节码文件

3.2 版本号

作者们识别了文件类型之后,接下去要精通版本号。版本号含主版本号和次版本号,都以各占2个字节。在此德姆o种为0X0000 0033。当中后边的0000是次版本号,后边的0033是主版本号。通过进制调换获得的是次版本号为0,主版本号为51。
从oracle官网大家能够精晓,51应和的正统jdk1.7,而其次版本为0,所以该文件的版本为1.7.0。借使急需表达,能够在用java --version命令输出版本号,只怕修改编译指标版本--target重新编写翻译,查看编写翻译后的字节码文件版本号是不是做了对应的退换。

至此,我们共领悟了前8字节的意义,上边讲讲常量池相关内容。

5.这一个数据结构在设想机的运维进程中又是何等被运用的?

用javac命令大概ide工具将该java源文件编写翻译成java字节码文件,编译好的字节码文件,大家得以观察一群16进制的字节。如若使用IDE去开垦,也许看见的是曾经被反编译的我们所纯熟的java代码,而那才是正经的字节码,那也是本文的内容主要。对这样一批字节码以为头痛,可是没什么,渐渐试着看懂它。

3.3 常量池

随后主版本号之后的正是常量池入口。常量池是Class文件中的能源旅馆,在接下去的剧情中咱们会发现众多地点会提到,如Class Name,Interfaces等。常量池中任重(Ren Zhong)而道远囤积2大类常量:字面量和符号援引。字面量如文本字符串,java中宣称为final的常量值等等,而符号援引如类和接口的大局限定名,字段的称谓和描述符,方法的名称和汇报符。

为何要求类和接口的全局限定名吧?系统援用类大概接口的时候不是透过内部存储器地址举办操作吗?这里咱们精心情忖,java虚构机在一贯不将类加载到内部存款和储蓄器的时候根本都未有分配内部存款和储蓄器地址,也就空中楼阁对内部存款和储蓄器的操作,所以java虚构机首先须要将类加载到虚拟机中,那么那么些历程规划对类的一定(需求加载A包下的B类,无法加载到别的包下边包车型客车其余类中),所以要求通过全局限定名来剖断唯一性。那就是为何叫做全局,限定的情致,也正是独一性。

在进展具体常量池深入分析在此以前,大家先来打听一下常量池的连串类型表:

4887王中王鉄算盘奖结果 6

jvm_constant.png

位置的表中描述了1第11中学数据类型的结构,其实在jdk1.7后头又加多了3种(CONSTANT_MethodHandle_info,CONSTANT_MethodType_info以及CONSTANT_InvokeDynamic_info)。那样算起来一共是14种。接下来大家遵照德姆o的字节码进行逐条翻译。

0x0015:由于常量池的数量不确定地点(n 2),所以要求在常量池的入口处放置一项u2档次的数码意味着常量池数量。因而该16进制是21,表示有20项常量,索引范围为1~20。明明是21,为何是20呢?因为Class文件格式规定,设计者就讲第0项保留出来了,以备后患。从此处我们领略接下去我们要求翻译出20项常量。
Constant #1 (一共有18个常量,那是首先个,由此及彼...)
0x0a-:从常量类型表中大家开掘,第贰个数据均是u1种类的tag,16进制的0a是十进制的10,对应表中的MethodRef_info。
0x-00 04-:Class_info索引项#4
0x-00 11-:NameAndType索引项#17
Constant #2
0x-09: FieldRef_info
0x0003 :Class_info索引项#3
0x0012:NameAndType索引项#18
Constant #3
0x07-: Class_info
0x-00 13-: 全局限定名常量索引为#19
Constant #4
0x-07 :Class_info
0x0014:全局限定名常量索引为#20
Constant #5
0x01:Utf-8_info
0x-00 01-:字符串长度为1(选拔接下去的叁个字节长度转义)
0x-61:"a"(十六进制转ASCII字符)
Constant #6
0x01:Utf-8_info
0x-00 01:字符串长度为1
0x-49:"I"
Constant #7
0x01:Utf-8_info
0x-00 06:字符串长度为6
0x-3c 696e 6974 3e-:"<init>"
Constant #8
0x01 :UTF-8_info
0x0003:字符串长度为3
0x2829 56:"()V"
Constant #9
0x-01:Utf-8_info
0x0004:字符串长度为4
0x436f 6465:"Code"
Constant #10
0x01:Utf-8_info
0x00 0f:字符串长度为15
0x4c 696e 654e 756d 6265 7254 6162 6c65:"LineNumberTable"
Constant #11
ox01: Utf-8_info
0x00 12字符串长度为18
0x-4c 6f63 616c 5661 7269 6162 6c65 5461 626c 65:"LocalVariableTable"
Constant #12
0x01:Utf-8_info
0x0004 字符串长度为4
0x7468 6973 :"this"
Constant #13
0x01:Utf-8_info
0x0f:字符串长度为15
0x4c 636f 6d2f 6465 6d6f 2f44 656d 6f3b:"Lcom/demo/Demo;"
Constant #14
0x01:Utf-8_info
0x00 0a:字符串长度为10
ox74 6573 744d 6574 686f 64:"testMethod"
Constant #15
0x01:Utf-8_info
0x000a:字符串长度为10
0x536f 7572 6365 4669 6c65 :"SourceFile"
Constant #16
0x01:Utf-8_info
0x0009:字符串长度为9
0x-44 656d 6f2e 6a61 7661 :"Demo.java"
Constant #17
0x0c :NameAndType_info
0x0007:字段只怕名字名称常量项索引#7
0x0008:字段或然措施描述符常量索引#8
Constant #18
0x0c:NameAndType_info
0x0005:字段恐怕名字名称常量项索引#5
0x0006:字段可能措施描述符常量索引#6
Constant #19
0x01:Utf-8_info
0x00 0d:字符串长度为13
0x63 6f6d 2f64 656d 6f2f 4465 6d6f:"com/demo/Demo"
Constant #20
0x01:Utf-8_info
0x00 10 :字符串长度为16
0x6a 6176 612f 6c61 6e67 2f4f 626a 6563 74 :"java/lang/Object"
到那边甘休大家分析了全部的常量。接下来是深入分析访谈标记位。

强大难题:

4887王中王鉄算盘奖结果 7java字节码的总览图

3.4 Access_Flag 访谈标记

会见标识信息包罗该Class文件是类依然接口,是或不是被定义成public,是不是是abstract,尽管是类,是不是被声称成final。通过上面包车型地铁源代码,大家明白该公文是类并且是public。

4887王中王鉄算盘奖结果 8

access_flag.png

0x 00 21:是0x0020和0x0001的并集。当中0x0020以此标识值涉及到了字节码指令,前期会有专项论题对字节码指令张开教学。期望中......

6.怎么着防守class文件被压迫?

咱俩也正是循序渐进下边包车型地铁逐一来对字节码举行解读的。一共含有10有个别,满含魔数,版本号,常量池等等,接下去我们依据顺序一步一步解读。

3.5 类索引

类索援用于规定类的全限定名
0x00 03 表示援用首个常量,相同的时候第四个常量援引第20个常量,查找得"com/demo/德姆o"。#3.#19

7.怎么着防备class文件被反编写翻译?

前4个字节表示的是魔数,对应德姆o的是 0XCAFE BABE。魔数是用来分别文件类型的一种标识,平日都以用文件的前多少个字节来表示。比方0XCAFE BABE表示的是class文件,那么有人会问,文件类型能够由此文件名后缀来剖断啊?是的,不过文件名是足以修改的,那么为了保险文件的安全性,将文件类型写在文件之中来确认保证不被篡改。从java的字节码文件类型大家见到,CAFE BABE翻译过来是咖啡珍宝之意,CAFE BABE = 咖啡。

3.6父类索引

0x00 04 同理:#4.#20(java/lang/Object)

 

识别了文件类型之后,接下去是JDK版本号。版本号含次版本号和程序版本号。对应德姆o的是0X0000 0033。当中前面包车型客车0000是次版本号,前边的0033是主版本号。通过进制调换获得的是次版本号为0,主版本号为51。

3.7 接口索引

通过java_byte.jpeg图大家明白,那个接口有2 n个字节,前八个字节表示的是接口数量,前面跟着就是接口的表。大家以此类未有任何接口,所以理应是0000。果不其然,查找字节码文件获得的正是0000。

class文件的组织结构定义如下:

从oracle官网大家能精晓,51一见还是的正经JDK1.7,而其次版本为0,所以该文件的版本为1.7.0。借使要求证实,能够在用java –version命令输出版本号,也许修改编写翻译目的版本–target重新编写翻译,查看编写翻译后的字节码文件版本号是或不是做了对应的修改。

3.8 字段表集结

字段表用于描述类和接口中声称的变量。这里的字段包罗了类等级变量以及实例变量,不过不包涵方法内部宣称的片段变量。
长久以来,接下去便是2 n个字段属性。我们独有一个属性a,按道理应该是0001。查找文件果不其然是0001。
那么接下去我们要对准如此的字段进行剖析。附上字段表结构图

4887王中王鉄算盘奖结果 9

字段表结构.png

0x00 02 :访问标识为private(自行检索字段访问标识)
0x00 05 : 字段名称索引为#5,对应的是"a"
0x 00 06 :描述符索引为#6,对应的是"I"
0x 00 00 :属性表数量为0,因而未曾属性表。
tips:一些不太重大的表(字段,方法访问标识表)能够自动物检疫索,这里就不贴出来了,幸免篇幅过大。

4887王中王鉄算盘奖结果 10

常量池是Class文件中的能源货仓,上边内容中广大地点会波及,如Class Name,Interfaces等。常量池中入眼囤积2大类常量:字面量和标记援用。字面量如文本字符串,java中宣称为final的常量值等等,而符号援用如类和接口的全局限定名,字段的称谓和描述符,方法的称谓和描述符。

3.9 方法

作者们唯有多个格局testMethod,根据道理应该前2个字节是0001。通过搜索开采是0x00 02。那是何等来头,这表示着有2个主意呢?且持续看......

4887王中王鉄算盘奖结果 11

艺术表结构.png

上海体育场面是一张方法表结构图,遵照那些图大家分析上边包车型客车字节码:

ClassFile{
magic                        u4,
minor_version                u2,
major_version                u2,
constant_pool_count            u2,
constant_pool                cp_info*constant_pool_count,
access_flags                 u2,
this_class                   u2,
super_class                  u2,
interface_count              u2,
interfaces                   u2 * interface_count,
fields_count                 u2,
fields                      field_info * fields_count,
methods_count                u2,
methods                      method_info * methods_count,
attributes_count             u2,
attributes                   attributes_info * attributes_count
}

为啥须求类和接口的大局限定名吧?系统引用类大概接口的时候不是通过内部存款和储蓄器地址进行操作吗?java设想机在尚未将类加载到内部存储器的时候根本都不曾分配内部存款和储蓄器地址,也就一纸空文对内存的操作,所以java设想机首先须求将类加载到虚构机中,那么那几个历程规划对类的固定(要求加载A包下的B类,无法加载到别的包上边包车型地铁其他类中),所以要求通过全局限定名来判断独一性。那就是干吗叫做全局,限定的意思,也便是独一性。

第1个方法:

0x00 01:访谈标识ACC_PUBLIC,注脚该措施是public。(可自行检索方法访谈标识表)
0x00 07:方法名索引为#7,对应的是"<init>"
0x00 08:方法描述符索引为#8,对应的是"()V"
0x00 01:属性表数量为1(一个属性表)
那么这里涉及到了属性表。什么是属性表呢?能够如此清楚,它是为着描述一些专有音讯的,上面包车型大巴办法包涵一张属性表。全部属性表的组织如下图:
四个u2的属性名称索引,三个u2的品质长度加上属性长度的info。
设想机标准预约义的天性有为数不少,比方Code,LineNumberTable,LocalVariableTable,SourceFile等等,这几个英特网能够查找到。

4887王中王鉄算盘奖结果 12

属性表结构.png

坚守地点的表结构深入分析获得下边消息:
0x0009:名称索引为#9("Code")。
0x000 00038:属性长度为56字节。
那么接下去分析三个Code属性表,依据下图分析

4887王中王鉄算盘奖结果 13

code.png

日前6个字节(名称索引2字节 属性长度4字节)已经解析过了,所以接下去便是深入分析剩下的56-6=50字节就能够。
0x00 02 :max_stack=2
0x00 01 : max_locals=1
0x00 0000 0a : code_length=10
0x2a b700 012a 04b5 0002 b1 : 那是code代码,能够经过编造机字节码指令展开搜寻。
2a=aload_0(将首先个援用变量推送到栈顶)
b7=invokespecial(调用父类构造方法)
00=什么都不做
01 =将null推送到栈顶
2a=同上
04=iconst_1 将int型1推送到栈顶
b5=put田野 为钦定的类的实例变量赋值
00= 同上
02=iconst_m1 将int型-1推送栈顶
b1=return 从当下格局重回void
整治,去除无动作指令获得上面
0 : aload_0
1 : invokespecial
4 : aload_0
5 : iconst_1
6 : putfield
9 : return
至于虚构机字节码指令那块内容,前期会一连深远下去...... 近来只须要明白就可以。接下来顺着Code属性表继续剖析下去:
0x00 00 : exception_table_length=0
0x00 02 : attributes_count=2(Code属性表内部还蕴藏2个属性表)
0x00 0a: 第一个属性表是"LineNumberTable"

4887王中王鉄算盘奖结果 14

LineNumberTable.png

0x00 0000 0a : "属性长度为10"
0x00 02 :line_number_table_length=2
line_number_table是一个多少为line_number_table_length,类型为line_number_info的集合,line_number_info表包罗了start_pc和line_number多少个u2品种的数目项,前面三个是字节码行号,前面一个是Java源码行号
0x00 00 : start_pc =0
0x00 03 : end_pc =3
0x00 04 : start_pc=4
0x00 04 : end_pc=4

0x00 0b 第贰个属性表是:"LocalVariableTable"

4887王中王鉄算盘奖结果 15

local_variable_table.png

4887王中王鉄算盘奖结果 16

local_variable_info.png

0x00 0000 0c:属性长度为12
0x00 01 : local_variable_table_length=1
接下来遵照local_variable_info表结构进行剖判:
0x00 00 : start_pc=0
0x00 0a:length=10
0x000c : name_index="this"
0x000d : descriptor_index #13 ("Lcom/demo/Demo")
0000 index=0
//-------到此处首先个点子就剖判实现了-------//
Method(<init>)--1个属性Code表-2个属性表(LineNumberTable ,LocalVariableTable)接下去分析第贰个格局

4887王中王鉄算盘奖结果 17

4887王中王鉄算盘奖结果 18常量池的体系类型表

第2个方法:

0x00 04:"protected"
0x00 0e: #14("testMethod")
0x00 08 : "()V"
0x0001 : 属性数量=1
0x0009 :"Code"
0x0000 002b 属性长度为43
剖判一个Code表
0000 :max_stack =0
0001 : max_local =1
0000 0001 : code_length =1
0xb1 : return(该措施重返void)
0x0000 分外表长度=0
0x0002 属性表长度为2
//第一个属性表
0x000a : #10,LineNumberTable
0x0000 0006 : 属性长度为6
0x0001 : line_number_length = 1
0x0000 : start_pc =0
0x0008 : end_pc =8
//第一个属性表
0x000b : #11 ,LocalVariableTable
0x0000 000c : 属性长度为12
0x0001 : local_variable_table_length =1
0x0000 :start_pc = 0
0x0001: length = 1
0x000c : name_index =#12 "this"
0x000d : 描述索引#13 "Lcom/demo/Demo;"
0000 index=0

//到此处结束,方法分析都做到了,回眸看最上部深入分析顺序图,大家接下去就要解析Attributes了。

以如下程序为例,对转移的class文件进行分析:

JDK1.7过后又追加了CONSTANT_MethodHandle_info,CONSTANT_MethodType_info和CONSTANT_InvokeDynamic_info,这样算起来一共是14种。

3.10 Attribute

0x0001 :同样的,表示有1个Attributes了。
0x000f : #15("SourceFile")
0x0000 0002 attribute_length=2
0x0010 : sourcefile_index = #16("Demo.java")
SourceFile属性用来记录生成该Class文件的源码文件名称。

4887王中王鉄算盘奖结果 19

source_file.jpeg

4887王中王鉄算盘奖结果 20

0×0015:由于常量池的数目不定点,所以须求在常量池的入口处放置一项u2(u2 – 2个字节)类型的数额意味着常量池数量。因而该16进制是21,表示有20项常量,索引范围为1~20。明明是21,为啥是20呢?因为Class文件格式规定,设计者就讲第0项保留出来了,以备后患。接下来要求翻译出20项常量。

4 另话

实在,我们写了那般多确实很费力,但是这种进程本身经验一次的所获所得依旧分化的。未来,使用java自带的反编写翻译器来解析字节码文件。
javap -verbose 德姆o //不用带后缀.class

4887王中王鉄算盘奖结果 21

javap_result.png

 1 //TestInterface.java
 2 public interface TestInterface {
 3     public void interface_method();
 4 }
 5 
 6 //TestClass.java
 7 public class TestClass implements TestInterface{
 8     private int private_global = 3;
 9     public int public_global;
10     private static final int sfi = 127;
11     public static final String sfs = "test strings";
12     private StringBuilder sb;
13     
14     public void method_1(){
15         private_global = public_global * 2;
16         sb.append(private_global);
17     }
18     
19     public void method_2(int pub){
20         public_global = pub;
21     }
22 
23     public void method_2(int pub, boolean flag){
24         int tmp = 5;
25         public_global = pub * 2   tmp;
26     }
27     
28     @Override
29     public void interface_method() {
30         method_1();
31     }
32     
33 }

Constant #1 (一共有二十一个常量,那是首先个,依此类推…)

0x0a-:从常量类型表中大家开掘,第一个数据均是u1(u1 – 1个字节)类型的tag,16进制的0a是十进制的10,对应表中的CONSTANT_MethodRef_info。

0x-00 04-:CONSTANT_Class_info索引项#4

0x-00 11-:CONSTANT_NameAndType_info索引项#17

5 总结

到此结束,批注达成了class文件的分析,那样今后我们也能看懂字节码文件了。通晓class文件的构造对前面更是驾驭设想机推行引擎相当的重大,所以那是基础并主要的一步。

4887王中王鉄算盘奖结果 22

Constant #2

0x-09: CONSTANT_FieldRef_info

0×0003 :CONSTANT_Class_info索引项#3

0×0012:CONSTANT_NameAndType_info索引项#18

6 工具:https://github.com/zxh0/classpy 那是一款拆解分析字节码文件的工具,相当好用。

1.magic(魔数) 值为0xcafebabe,没有特意的含义,放在文件头并精选取来标记改文件是三个class文件。

Constant #3

0×07-: CONSTANT_Class_info

0x-00 13-: 全局限定名常量索引为#19

4887王中王鉄算盘奖结果 23

Constant #4

0x-07 :CONSTANT_Class_info

0×0014:全局限定名常量索引为#20

 

Constant #5

0×01:CONSTANT_Utf-8_info

0x-00 01-:字符串长度为1(采用接下去的多少个字节长度转义)

0x-61:”a”(十六进制转ASCII字符)

2.minor_version/major_version(次版本号和主版本号)

Constant #6

0×01:CONSTANT_Utf-8_info

0x-00 01:字符串长度为1

0x-49:”I”

4887王中王鉄算盘奖结果 24

Constant #7

0×01:CONSTANT_Utf-8_info

0x-00 06:字符串长度为6

0x-3c 696e 6974 3e-:”<init>”

次版本号和主版本号分别为0x0000和0x0032(50),即主版本号位50,次版本号为0

Constant #8

0×01 :CONSTANT_UTF-8_info

0×0003:字符串长度为3

0×2829 56:”()V”

 

Constant #9

0x-01:CONSTANT_Utf-8_info

0×0004:字符串长度为4

0x436f 6465:”Code”

3.constant_pool_count/constant_pool(常量池数量和常量池)

Constant #10

0×01:CONSTANT_Utf-8_info

0×00 0f:字符串长度为15

0x4c 696e 654e 756d 6265 7254 6162 6c65:”LineNumberTable”

常量池保存了文本中类或接口相关的整个常量,字面常量(直接量),如文字字符串、final变量值,以及符号援用,如类或接口的全限定名、方法或字段的简要名称和描述符

Constant #11

ox01: CONSTANT_Utf-8_info

0×00 12字符串长度为18

0x-4c 6f63 616c 5661 7269 6162 6c65 5461 626c 65:”LocalVariableTable”

个中,全限定名用以在此时此刻命名空间内唯一标记类或接口,在java语言中如java.lang.Object,在class文件中,会将'.'用'/'替代,即表示为java/lang/Object 简单名称就算简单的格局名或变量名的字符串,如java.lang.Object的积极分子方法wait()的大致名叫"wait"。

Constant #12

0×01:CONSTANT_Utf-8_info

0×0004 字符串长度为4

0×7468 6973 :”this”

而独有大概名称是心余力绌独一分明调用的方式是哪贰个,由于Java语言的特征,方法大概被重写或重载, 所以还亟需基于办法的重返值、参数数量、类型、顺序来确定四个措施描述符来独一标识该方法,字段的陈说符则简单得多,只必要付出字段的等级次序 描述符让大家联想起PE/ELF文件的函数签字,它由上下文非亲非故语法定义:

Constant #13

0×01:CONSTANT_Utf-8_info

0x0f:字符串长度为15

0x4c 636f 6d2f 6465 6d6f 2f44 656d 6f3b:”Lcom/demo/Demo;”

4887王中王鉄算盘奖结果 25

Constant #14

0×01:CONSTANT_Utf-8_info

0×00 0a:字符串长度为10

ox74 6573 744d 6574 686f 64:”testMethod”

FieldDescriptor:
            FieldType
ComponentType:
            FieldType
FieldType:
            BaseType
            ObjectType
            ArrayType
BaseType:
            B
            C
            D
            F
            I
            J
            S
            Z
ObjectType:
            L<classname>;
ArrayType:
            [ComponentType
MethodDescriptor:
            (ParameterDescriptor*) ReturnDescriptor
ParameterDescriptor:
            FieldType
ReturnDescriptor:
            FieldType
            V

Constant #15

0×01:CONSTANT_Utf-8_info

0x000a:字符串长度为10

0x536f 7572 6365 4669 6c65 :”SourceFile”

4887王中王鉄算盘奖结果 26

Constant #16

0×01:CONSTANT_Utf-8_info

0×0009:字符串长度为9

0x-44 656d 6f2e 6a61 7661 :”Demo.java”

其得了符号如下:

Constant #17

0x0c :CONSTANT_NameAndType_info

0×0007:字段也许名字名称常量项索引#7

0×0008:字段只怕措施描述符常量索引#8

4887王中王鉄算盘奖结果 27

Constant #18

0x0c:CONSTANT_NameAndType_info

0×0005:字段可能名字名称常量项索引#5

0×0006:字段大概措施描述符常量索引#6

以深入java设想机上的亲自去做作为参谋:

Constant #19

0×01:CONSTANT_Utf-8_info

0×00 0d:字符串长度为13

0×63 6f6d 2f64 656d 6f2f 4465 6d6f:”com/demo/Demo”

     4887王中王鉄算盘奖结果 28

Constant #20

0×01:CONSTANT_Utf-8_info

0×00 10 :字符串长度为16

0x6a 6176 612f 6c61 6e67 2f4f 626a 6563 74 :”java/lang/Object”

走访标识消息包蕴该Class文件是类依旧接口,是或不是被定义成public,是或不是是abstract,借使是类,是或不是被声称成final。通过上面的源代码,我们通晓该文件是类并且是public。

4887王中王鉄算盘奖结果 29Access Flags4887王中王鉄算盘奖结果 30Access Flags

0x00 21:是0×0020和0×0001的并集。

类索援引于规定类的全限定名

0×00 03:表示引用首个常量(上文2.3中的第2个常量),同一时候第二个常量援引第十几个常量(上文2.3中的第二13个常量),查找得”com/demo/德姆o”。

0×00 04:表示引用第2个常量(上文2.3中的第二个常量),同期首个常量引用第二十一个常量(上文2.3中的第二十个常量),查找得”java/lang/Object”。

4887王中王鉄算盘奖结果 31

2.7、接口索引(Interfaces:2 n个字节)

以此接口有2 n个字节,前四个字节表示的是接口数量,前面随着正是接口的表。字节码为0000验证那么些类未有另外接口。

字段表用于描述类和接口中宣示的变量,这里的字段包罗了类等第变量以及实例变量,不过不包蕴方法内部宣称的局部变量。

以此接口有2 n个字节,前多少个字节表示的是宣称的变量数量,前边跟着正是声称的变量。字节码为0001注脚那些类有贰个宣称的变量。

那么接下去大家要指向如此的字段举行分析。

4887王中王鉄算盘奖结果 32字段表结构

0×00 02:访谈标识为private

0×00 05:字段名称索引为#5,对应的是”a”

0x00 06:描述符索引为#6,对应的是”I”

0x00 00:属性表数量为0,由此并未属性表。

0x00 02:表示有多少个法子

4887王中王鉄算盘奖结果 33措施表结构

上边看class文件内常量池部分: 首先是常量池数:即(0x35)五十七个常量池

率先个方法

0×00 01:访谈标记 ACC_PUBLIC,申明该办法是public。

0×00 07:方法名索引为#7,对应的是””

0×00 08:方法描述符索引为#8,对应的是”()V”

0×00 01:属性表数量为1

4887王中王鉄算盘奖结果 34属性表结构

二个u2的习性名称索引,三个u2的本性长度加上属性长度的info。

设想机规范预订义的性质有非常多,举个例子Code,LineNumberTable,LocalVariableTable,SourceFile等等,这几个互连网能够寻觅到。

依据上面包车型地铁表结构剖析获得上边消息:

0×00 09:名称索引为#9。

0×00 0000 38:属性长度为56字节。

4887王中王鉄算盘奖结果 35Code属性表结构

日前6个字节(名称索引2字节 属性长度4字节)已经分析过了,所以接下去就是解析剩下的56-6=50字节就可以。

0×00 02:max_stack=2

0×00 01:max_locals=1

0×00 0000 0a:code_length=10

0x2a b700 012a 04b5 0002 b1:那是code代码,能够通过编造机字节码指令张开搜寻。

2a=aload_0(将率先个援用变量推送到栈顶)

b7=invokespecial

00=什么都不做

01=将null推送到栈顶

2a=同上

04=iconst_1 将int型1推送到栈顶

b5=put田野(field) 为钦赐的类的实例变量赋值

00= 同上

02=iconst_m1 将int型-1推送栈顶

b1=return 从当下格局重临void

重新整建,去除无动作指令获得上面

0 : aload_0

1 : invokespecial

4 : aload_0

5 : iconst_1

6 : putfield

9 : return

至于设想机字节码指令那块内容,早先时期会持续深切下去…… 近期只需求通晓就能够。接下来顺着Code属性表继续解析下去:

0×00 00:exception_table_length=0

0×00 02:attributes_count=2(Code属性表内部还包含2个属性表)

4887王中王鉄算盘奖结果 36LineNumberTable属性结构

0×00 0a:第多个属性表是”LineNumberTable”

0×00 0000 0a:“属性长度为10″

0×00 02:line_number_table_length=2

line_number_table是贰个数据为line_number_table_length,类型为line_number_info的集合,line_number_info表蕴涵了start_pc和line_number七个u2类其余数据项,前边三个是字节码行号,前者是Java源码行号

0×00 00:start_pc=0

0×00 03:end_pc=3

0×00 04:start_pc=4

0×00 04:end_pc=4

4887王中王鉄算盘奖结果 37LocalVariableTable属性结构

0×00 0b:首个属性表是”LocalVariableTable”

0×00 0000 0c:属性长度为12

0×00 01:local_variable_table_length=1

4887王中王鉄算盘奖结果 38local_variable_info表结构

下一场根据local_variable_info表结构举办深入分析:

0×00 00:start_pc=0

0×00 0a:length=10

0x000c:name_index=”this”

0x000d:descriptor_index #13 (“Lcom/demo/Demo”)

0x0000:index=0

4887王中王鉄算盘奖结果 39

第三个艺术

0×00 04:”protected”

0×00 0e:#14(”testMethod”)

0×00 08:“()V”

0×0001:属性数据=1

0×0009:”Code”

0×0000 002b:属性长度为43

解析一个Code表

0000:max_stack =0

0001:max_local =1

0000 0001:code_length =1

0xb1:return(该措施重返void)

0×0000:万分表长度=0

0×0002:属性表长度为2

//第二个属性表

0x000a:#10,LineNumberTable

0×0000 0006:属性长度为6

0×0001:line_number_length = 1

0×0000:start_pc =0

0×0008:end_pc =8

//第3个属性表

0x000b:#11 ,LocalVariableTable

0×0000 000c:属性长度为12

0×0001:local_variable_table_length =1

0×0000:start_pc = 0

0×0001:length = 1

0x000c:name_index =#12 “this”

0x000d:描述索引#13 “Lcom/demo/Demo;”

0x0000:index=0

0×0001:同样的,表示有1个Attributes了。

0x000f:#15(“SourceFile”)

0×0000 0002:attribute_length=2

0×0010:sourcefile_index = #16(“Demo.java”)

4887王中王鉄算盘奖结果 40SourceFile属性结构

SourceFile属性用来记录生成该Class文件的源码文件名称。

Java虚构机将常量池组织改为列表(能够看做是叁个常量池的数组)的花样,常量池内容大概指向任何常量池,并且class文件中别的一些内容也说不定指向常量池入口,那些常量池通过该常量池在常量池列表中的索引来恒定,常量池列表的0号常量池其实是空的,作为常量池的NULL引用,即常量池列表的第一项实际上是1号常量池,常量池列表实际上独有constant_pool_count - 1个常量池项。 随后是常量池列表,常量池的构造如下:

cp_info{
tag,
info
}

常量池的原则性第一个字节是常量值标签,用来描述该常量池保存内容的体系,常量池标记和含义如下:

4887王中王鉄算盘奖结果 41 

根据常量池标识tag的差异,info有不一样的团组织议程:

(1).CONSTANT_Utf8结构:

4887王中王鉄算盘奖结果 42 

(能够看出length由2个字节表示,最大尺寸就活该是65536字节)

该项目是三个尺寸可变(长度为length)的常量字符串表,用来积存以下项目标字符串:

  • 文字字符串,如String对象的内容
  • 此时此刻类或接口的全限定名
  • 最近类的超类的全限定名
  • 眼前类或接口的父接口的全限定名
  • 字段的轻松名称或描述符
  • 艺术的简短名称或描述符
  • 引用类或接口的全限定名
  • 援用字段的总结名称和描述符
  • 援用方法的简练名称和叙述符

字符的寄存: 
对于0x0001-0x007f的字符将动用四个字节(该字节的0-6位,第7位为0)寄放 
对于0x080-0x07ff的字符将接纳五个字节(依次高字节的0-5位和低字节的0-4位,剩余位分别为10、110)存放 

4887王中王鉄算盘奖结果 43

 

对于0x0800-0xffff的字符将应用3个字节(依次为高字节的0-5中路字节的0-5,和低字节的0-3位,剩余位分别为10、10、1110)存放。

4887王中王鉄算盘奖结果 44

(2).CONSTANT_Integer结构:

Type Name Count
u4 bytes 1

 

 

按高位在前的格式存储int型数据

(3).CONSTANT_Float结构:

Type Name Count
u4 bytes 1

 

 

按高位在前的格式存款和储蓄float型数据 
(4).CONSTANT_Doube结构:

Type Name Count
u8 bytes 1

 

 

按高位在前的格式存款和储蓄double型数据 
(5).CONSTANT_Long结构:

Type Name Count
u8 bytes 1

 

 

按高位在前的格式存款和储蓄long型数据 
(6).CONSTANT_Class结构:

Type Name Count
u2 name_index 1

 

 

name_index为类依旧接口符号援用的CONSTANT_Utf8常量池的目录(全限定名) 
(7).CONSTANT_String结构:

Type Name Count
u2 sring_index 1

 

 

string_index为字符串的CONSTANT_Utf8常量池的索引 
(8).CONSTANT_Fieldref结构: 
汇报了指向字段的标志引用,其内容分两项表示,一项为被引述字段所在类或接口的CONSTANT_Class常量池索引,一项为字段的简易名称和描述符,指向三个CONSTANT_NameAndType常量池

Type Name Count
u2 class_index 1
u2 name_and_type_index 1

 

 

 

(9).CONSTANT_Methodref结构: 
与CONSTANT_Fieldref类似,描述了指向类中宣示的不二诀窍的号子援引,其剧情分两项表示,一项为被援用方法所在类的CONSTANT_Class常量池索引,一项为艺术的简短名称和描述符,指向三个CONSTANT_NameAndType常量池

Type Name Count
u2 class_index 1
u2 name_and_type_index 1

 

 

 

(10).CONSTANT_InterfaceMethodref结构: 
与CONSTANT_Methodref类似,描述了指向接口中宣称的措施的号子引用,其剧情分两项表示,一项为被引用方法所在接口的CONSTANT_Class常量池索引,一项为方式的简约名称和描述符,指向八个CONSTANT_NameAndType常量池

Type Name Count
u2 class_index 1
u2 name_and_type_index 1

 

 

 

(11).CONSTANT_NameAndType结构: 
能够预感,该常量池提供了所引述字段或情势的简要名称和常量池入口

Type Name Count
u2 class_index 1
u2 name_and_type_index 1

 

 

 

在乎区分class_index指向的是对应类的常量池,该CONSTANT_Class常量池指向贰个全限定名的CONSTANT_Utf8字符串常量池 
常量池有个别的解析能够参照 

4.access_flags 
该项2字节标注了所定义类或接口的类型音讯

4887王中王鉄算盘奖结果 45 

该公文中access_flags为0x0021 ,可知该类是public super类型。

4887王中王鉄算盘奖结果 46

5.this_class(当前类) 
该项2字节注解了所定义类或接口的CONSTANT_Class常量池索引,最终指向全限定名”TestClass” 

4887王中王鉄算盘奖结果 47

6.super_class(超类) 
该项2字节标明了所定义类的超类的CONSTANT_Class常量池索引,最后指向全限定名”java/lang/Object”

4887王中王鉄算盘奖结果 48

7.interfaces_count/interfaces(接口数和接口) 
首先2字节是在此类中一直促成或扩充的接口数,后边紧随若干个(接口数)2字节,代表所平素实现或扩张的接口的CONSTANT_Class常量池的索引 
4887王中王鉄算盘奖结果 49
这里只兑现了三个接口,就是5号常量池,即全限定名”TestInterface”所定义的接口

8.fields_count/田野同志s(字段数和字段) 
fields_count 是类变量(静态变量)和实例变量(非静态变量)的字段数总和,与constant_pool组织格局类似,前面是田野同志s_count个 field_info,须求在乎的是,当前类的字段不会包涵其超类或父接口中承继的字段,也会含有在Java源文件中并未有不过在编写翻译时累加的部分字段。 田野(field)_info结构如下:

4887王中王鉄算盘奖结果 50

field_info{
access_flags             u2,
name_index               u2,
descriptor_index         u2,
attributes_count         u2,
attributes               attributes_info * attributes_cout 
}

4887王中王鉄算盘奖结果 51

(1).字段的accesss_flags与陈述当前类的access_flags不同:

  4887王中王鉄算盘奖结果 52 

类中注脚的字段,只可以具有ACC_PUBLIC、ACC_PRIVATE、ACC_PROTECTED八个标记中的三个。ACC_FINAL 
和ACC_VOLATILE 不可能而且安装。全体接口中声称的字段必需有ACC_PUBLIC、ACC_STATIC、ACC_FINAL 那三种标记。 
(2).name_index为该字段的轻便名称的CONSTANT_Utf8常量池索引 
(3).descriptor_index为该字段的陈诉符的CONSTANT_Utf8常量池索引 
(4).attributes_count和attributes是attributes_count个attribute_info结构所发布的属性集结。在字段域出现的习性有ConstantValue(final常量)、Deprecated(被剥夺的指令符)、Synthetic(编写翻译器产生的提示符)

属性出现在ClassFile、 field_info、method_info、Code_attribute中。全数Java设想机必需能够辨识Code、 ConstantValue、Exception。对于可以平常达成Java/Java2阳台类库的虚构机必得能够辨识InnerClass和 Synthetic属性。

4887王中王鉄算盘奖结果 53

attribute_info的布局如下:

attribute_info{
attribute_name_index            u2,
attribute_length                u4,
info                            u1,
}

attribute_name_index为描述属性的字符串名称(即上述列出属性名)的CONSTANT_Utf8常量池索引, 
attribute_length为前边属性内容的尺寸 
那边先介绍将字段只怕用到的ConstantValue、Deprecated和Synthetic属性 
(1).ConstantValue

Type Name Count
u2 constantvalue_index 1

 

 

该属性用于描述值为常量的字段,并且在含有该属性的字段其access_flag必须为ACC_STATIC,以申明那是二个静态常量。 
constantvalue_index指向提供常量值的常量池索引(别的,ConstantValue对应的性情的attribute_length始终为2) 
(2).Deprecated 
被@Deprecated所讲明的字段、方法或项目,表示即使该字段、方法或项目还是存在,不过不建议选择,其在以往的本子中恐怕会被移除 
Deprecated对应的习性的attribute_length值始终为0 
(3).Synthetic 
用来指明为编写翻译器所发生的字段、方法或项目 
同等,那是二个定位长度属性,其 
对应的习性的attribute_length值始终为0

class文件field域解析: 
第一由开端四个字节看出有5个田野同志_info 
4887王中王鉄算盘奖结果 54

field1: 
access_flag为ACC_PENCOREIVATE,标记其为private类型 
name_index为0x0007,指向7号常量池,即轻松名为”private_global” 
descriptor_index为0x0008,指向8号常量池,即描述符为”I” 
attributes_count为0,即未有另外属性 
4887王中王鉄算盘奖结果 55

field2: 
access_flag为ACC_PUBLIC,标识其为public类型 
name_index为0x0009,指向9号常量池,即轻松名称叫”public_global” 
descriptor_index为0x0008,指向8号常量池,即描述符为”I” 
attributes_count为0,即未有另外属性 
4887王中王鉄算盘奖结果 56

field3: 
access_flag为0x0010|0x0008|0x0002,即ACC_FINAL | ACC_STATIC | ACC_P悍马H2IVATE,标记其为private static final类型 
name_index为0x000A,指向10号常量池,即轻易名称叫”sfi” 
descriptor_index为0x0008,指向8号常量池,即描述符为”I” 
attributes_count为1,即有三个属性 
4887王中王鉄算盘奖结果 57
该属性的 
attribute_name_index为0x000B,指向11号常量池,即”ConstantValue”属性 
attribute_length为2,即固定2个字节 
constantvalue_index为0x000C,指向12号常量池,即sfi的值为”127”(这里依然字符串) 
4887王中王鉄算盘奖结果 58

field4: 
access_flag为0x0010|0x0008|0x0001,即ACC_FINAL | ACC_STATIC | ACC_PUBLIC,标记其为public static final类型 
name_index为0x000D,指向13号常量池,即轻松名为”sfs” 
descriptor_index为0x000E,指向14号常量池,即描述符为”Ljava/lang/String;” 
attributes_count为1,即有四个属性 
4887王中王鉄算盘奖结果 59
该属性的 
attribute_name_index为0x000B,指向11号常量池,即”ConstantValue”属性 
attribute_length为2,即固定2个字节 
constantvalue_index为0x000F,指向15号常量池,即sfs的值为”test strings” 
4887王中王鉄算盘奖结果 60

field5: 
access_flag为ACC_P福睿斯IVATE,标识其为private类型 
name_index为0x0011,指向17号常量池,即轻巧名称叫”sb” 
descriptor_index为0x0012,指向18号常量池,即描述符为”Ljava/lang/StringBuilder;” 
attributes_count为0,即未有别的属性 
4887王中王鉄算盘奖结果 61

9.methods_count/methods(方法数/方法) 
方法域的method_info结构与字段域是千篇一律的,即

4887王中王鉄算盘奖结果 62

method_info{
access_flags             u2,
name_index               u2,
descriptor_index         u2,
attributes_count         u2,
attributes               attributes_info * attributes_cout 
}

4887王中王鉄算盘奖结果 63

不过其access_flag有个别区别

 4887王中王鉄算盘奖结果 64

借使三个办法是架空方法,那么它就不可能为private、static、final、synchronized、native和strict类型

在方法域出现的性情有Code、Deprecated、Exceptions、Synthetic 
下边介绍新出现的三种属性Code和Exceptions: 
(1).Code 
其info域的布局如下

4887王中王鉄算盘奖结果 65 

其中:

  • max_stack标记该办法试行的轻巧时刻,其操作数栈的最大尺寸(以字为单位)
  • max_locals标识改措施的有的变量所需存放空间的尺寸(以字为单位)
  • code_length给出了该方法字节码部分的尺寸(以字节为单位)
  • code_length长度的字节码
  • exception_table_length是不行表的长短,紧接着是exception_table_length个exception_info所描述的要命消息
  • 谈起底正是该段代码的属性描述,这是叁个嵌套的习性描述,会冒出七个新的习性LineNumberTable和LocalVariableTable,即行号表和局地变量表

首先看exception_table_info的组织,可以预感,八个万分在代码中的描述就务须包括成效域、至极类型和特别管理三有的剧情,看看exception_table_info是或不是那般社团的

4887王中王鉄算盘奖结果 66

exception_table_info{
start_pc             u2,
end_pc               u2,
handler_pc           u2,
catch_type           u2,
}

4887王中王鉄算盘奖结果 67

意料之中,start_pc正是可怜管理器发轫地方相对该段代码的偏移量, 
end_pc便是非常处理器截至地方相对该段代码的偏移量, 
handler_pc就是老大管理器第一条指令相对该段代码的偏移量 
catch_type指向描述该非常类型(java/lang/Throwable或其子类)的CONSTANT_Class常量池索引,二若catch_type为0,那么卓殊处理器将拍卖全部非常

(2).LineNumberTable 
行号表与ELF/PE文件看上去具备不谋而合之妙,它同样创造了法子的字节码偏移量和源代码行号之间的投射关系。其info域结构如下

Type Name Count
u2 line_number_table_length 1
line_number_info line_number_table line_number_table_length

 

 

 

line_number_table_length描述了行号表的项数,注意,实际不是行号表各种实际不是逐行对应,而是也许依照任何顺序排列,并且恐怕多项对应同一行。 
line_number_info的结构如下:

line_number_info{
start_pc           u2,
line_number        u2,
}

其中,start_pc描述了该行发轫第七个字节码对应当段代码的偏移量,line_number描述了相应的行号。

(3).LocalVariableTable 
那边由LocalVariableTable保存了章程的栈帧中有些变量域源代码中有的变量的名号和陈述符之间的映射关系。

 4887王中王鉄算盘奖结果 68

一样,局地变量表也是以local_variable_table_length个local_variable_info结构进行公司的 

local_variable_info的构造如下:

4887王中王鉄算盘奖结果 69

local_variable_info{
start_pc                u2,
length                  u2,
name_index              u2,
descriptor_index        u2,
index                   u2,
}

4887王中王鉄算盘奖结果 70

  • start_pc为该段代码中指令起初地方的方便
  • length为从start_pc开头的、全体片段变量有效的代码的长度(即由[start_pc, start_pc length]呈报了一部分变量的功效域)
  • name_index为该有的变量轻易名称的CONSTANT_Utf8常量池索引
  • descriptor_index为该部分变量描述符的CONSTANT_Utf8常量池索引
  • index为在此方法的栈帧中部分变量部分的索引 
    亟需掌握,local_variable_info建设构造了源代码中有的变量名称、类型和其在字节码的功用域、以及栈帧中的索引之间的关系,因方法区这一奇特的结构而存在。

(4).Exceptions属性 
分别于描述Code属性的exception_table部分,这里是艺术或许会抛出的不行,而非包围代码的try/catch十分。Exceptions属性的info域格式如下:

Type Name Count
u2 number_of_exceptions 1
u2 exception_index_table number_of_exceptions

 

 

 

exception_index_table是该格局抛出的十分类型的CONSTANT_Class常量池索引,number_of_exceptions建议了抛出拾壹分类型的数据。 

methods部分的深入分析能够参见 
10.attributes_count/attributes(属性数和属性) 
说起底还应该有三种性格:InnerClass和SourceFile 
(1).SourceFile 
其info结构为:

Type Name Count
u2 sourcefile_index 1

 

 

交付了指向源文件名的CONSTANT_Utf8常量池索引 
如该class文件最终的attributes_count为1,其 
attribute_name_index为0x0033,指向51号常量池,即”SourceFile”属性 
attribute_length为0x02,即2个字节 
sourcefile_index为0x0034,指向52号常量池,即源文件名叫”TestClass.java”

(2).InnerClasses

Type Name Count
u2 number_of_classes 1
classes_info classes number_of_classes

 

 

 

classses_info描述了里面类(成员嵌套类、局地嵌套类和无名嵌套类)的音讯,其结构如下:

4887王中王鉄算盘奖结果 71

classes_info{
inner_class_info_index        u2,
outer_class_info_index        u2,
inner_name_index              u2,
inner_class_access_flags      u2,
}

4887王中王鉄算盘奖结果 72

  • inner_class_info_index指向所定义的里边类的CONSTANT_Class常量池的目录
  • outer_class_info_index指向该内部类的外侧类的CONSTANT_Class常量池的目录,若该内部类不是三个成员嵌套类,其值为0
  • inner_name_index为该内部类的简便名称的CONSTANT_Utf8_info索引,当该内部类为无名氏内部类时,其值为0
  • inner_class_access_flags是对该内部类的访谈标识

以如下内容为例 
 4887王中王鉄算盘奖结果 73
其生成的class文件如下: 
4887王中王鉄算盘奖结果 74
其InnerClasses属性内容为: 
4887王中王鉄算盘奖结果 75
当中无名氏内部类Runnable的全限定名叫InnerClassTest$1,由于其不是一个成员嵌套类(该类是局地嵌套类),其 outer_class_info_index 为0,由于此类是一个佚名内部类,其inner_name_index为0(即简单名为空) 
局地嵌套类NestedLocalClass的全限定名叫InnerClassTest$1NestedLocalClass,由于其不是三个成员嵌套类, 其outer_class_info_index为0,其轻便名称叫”NestedLocalClass”,access_flag为final 
成员嵌套类NestedMemberClass的全限定名称为InnerClassTest$NestedMemberClass,其简要名称叫”NestedMemberClass”,access_flag为public static final

除此以外,大家注意到内嵌类的内容会定义在各自的class文件中,而不会产出在InnerClassTest类的class文件中,在NestedMemberClass的class文件中存有如下的InnerClasses属性: 
4887王中王鉄算盘奖结果 76
在subClass的class文件中也具备如下的InnerClasses属性: 
4887王中王鉄算盘奖结果 77
能够看来,各样作为外界类的个中类的类都将保留在该外围类的CONSTANT_Class常量池中,并有二个inner_class_info结构加以描述 
如InnerClassTest的3个里头类项,NestedMemberClass的第二个里头类项
 
可是急需专心,subClass在被未有被InnerClassTest直接援用时,是不会产出在InnerClassTest的InnerClasses属性中的 
另外,InnerClasses还将发布内嵌类型的外围类,作为内部类的有着外场类都将保留在该内部类的CONSTANT_Class常量池中,并有三个inner_class_info结构加以描述 
如NestedMemberClass的首个外表类项,subClass的2个外表类项

转:http://www.cnblogs.com/iceAeterNa/p/4874197.html

本文由4887王中王鉄算盘奖结果发布于王中王鉄算盘,转载请注明出处:实例分析Java【4887王中王鉄算盘奖结果】,一文让

关键词:

最火资讯