java文件
package com.kq.jvm;
public class SimpleDemo {
private long id;
public String name;
}
javap解析文件
class文件
00000000: CA FE BA BE 00 00 00 34 00 14 0A 00 03 00 11 07 J~:>...4........
00000010: 00 12 07 00 13 01 00 02 69 64 01 00 01 4A 01 00 ........id...J..
00000020: 04 6E 61 6D 65 01 00 12 4C 6A 61 76 61 2F 6C 61 .name...Ljava/la
00000030: 6E 67 2F 53 74 72 69 6E 67 3B 01 00 06 3C 69 6E ng/String;...<in
00000040: 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 it>...()V...Code
00000050: 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 ...LineNumberTab
00000060: 6C 65 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 le...LocalVariab
00000070: 6C 65 54 61 62 6C 65 01 00 04 74 68 69 73 01 00 leTable...this..
00000080: 17 4C 63 6F 6D 2F 6B 71 2F 6A 76 6D 2F 53 69 6D .Lcom/kq/jvm/Sim
00000090: 70 6C 65 44 65 6D 6F 3B 01 00 0A 53 6F 75 72 63 pleDemo;...Sourc
000000a0: 65 46 69 6C 65 01 00 0F 53 69 6D 70 6C 65 44 65 eFile...SimpleDe
000000b0: 6D 6F 2E 6A 61 76 61 0C 00 08 00 09 01 00 15 63 mo.java........c
000000c0: 6F 6D 2F 6B 71 2F 6A 76 6D 2F 53 69 6D 70 6C 65 om/kq/jvm/Simple
000000d0: 44 65 6D 6F 01 00 10 6A 61 76 61 2F 6C 61 6E 67 Demo...java/lang
000000e0: 2F 4F 62 6A 65 63 74 00 21 00 02 00 03 00 00 00 /Object.!.......
000000f0: 02 00 02 00 04 00 05 00 00 00 01 00 06 00 07 00 ................
00000100: 00 00 01 00 01 00 08 00 09 00 01 00 0A 00 00 00 ................
00000110: 2F 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 /........*7..1..
00000120: 00 02 00 0B 00 00 00 06 00 01 00 00 00 08 00 0C ................
00000130: 00 00 00 0C 00 01 00 00 00 05 00 0D 00 0E 00 00 ................
00000140: 00 01 00 0F 00 00 00 02 00 10 ..........
magic - u4
0xCAFEBABE
CA FE BA BE
minor_version - u2
次版本号
00 00
major_version - u2
主版本号
# 00 34
52 是 jdk1.8
constant_pool_count - u2
常量池个数
第一个是null
# 00 14
常量池20个
constant_pool
第1个常量池 0A
0A是10,是CONSTANT_Methodref
CONSTANT_Methodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
# 0A 00 03 00 11
指向 03 和 17
第2个常量池 07
07类型是CONSTANT_Class
CONSTANT_Class_info {
u1 tag;
u2 name_index;
}
07 00 12
# name_index=#18
第3个常量池 07
同上第2个常量
07 00 13
# name_index=#19
第4个常量池 01
01是CONSTANT_Utf8
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
# 01 00 02 69 64
tag=01
length=00 02
02后面取2位,就是bytes数据 (6964=id)
第5个常量池 01
同上
# 01 00 01 4A
4A = J
第6个常量池 01
同上
# 01 00 04 6E 61 6D 65
6E = n
61 = a
6D = m
65 = e
第7个常量池 01
同上
# 18个
01 00 12
# Ljava/lang/String;
4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b
第8个常量池 01
同上
# 6个
01 00 06
# <init>
3c 69 6e 69 74 3e
第9个常量池 01
同上
# 3个
01 00 03
# ()V
28 29 56
第10个常量池 01
同上
# 4个
01 00 04
# Code
43 6F 64 65
第11个常量池 01
同上
# 15个
01 00 0f
# LineNumberTable
4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65
第12个常量池 01
同上
# 18个
01 00 12
# LocalVariableTable
4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65
第13个常量池 01
同上
# 4个
01 00 04
# this
74 68 69 73
第14个常量池 01
同上
# 23个
01 00 17
# Lcom/kq/jvm/SimpleDemo;
4C 63 6F 6D 2F 6B 71 2F 6A 76 6D 2F 53 69 6D 70 6C 65 44 65 6D 6F 3B
第15个常量池 01
同上
# 10个
01 00 0A
# SourceFile
53 6F 75 72 63 65 46 69 6C 65
第16个常量池 01
同上
# 15个
01 00 0F
# SimpleDemo.java
53 69 6D 70 6C 65 44 65 6D 6F 2E 6A 61 76 61
第17个常量池 0C
CONSTANT_NameAndType_info {
u1 tag;
u2 name_index;
u2 descriptor_index;
}
The value of the
name_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structureThe value of the
descriptor_index
item must be a valid index into theconstant_pool
table. Theconstant_pool
entry at that index must be aCONSTANT_Utf8_info
structure
0C 00 08 00 09
name_index = #8 (常量池第8个位置)
descriptor_index = #9 (常量池第9个位置)
第18个常量池 01
CONSTANT_Utf8_info
# 21个
01 00 15
# com/kq/jvm/SimpleDemo
63 6F 6D 2F 6B 71 2F 6A 76 6D 2F 53 69 6D 70 6C 65 44 65 6D 6F
第19个常量池 01
CONSTANT_Utf8_info
# 16个位置
01 00 10
# java/lang/Object
6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74
access_flags u2
# 33
00 21
this_class u2
com/kq/jvm/SimpleDemo
# #2 第2个常量池
00 02
access_flags下面的两个字节叫做this_class, 它是对当前类的描述。
它的两个字节的数据是对常量池中的一个CONSTANT_Class_info数据项的一个索引。
CONSTANT_Class_info中有一个字段叫做name_index , 指向一个CONSTANT_Utf8_info,
在这个CONSTANT_Utf8_info 中存放着当前类的全限定名
super_class u2
java/lang/Object
# 03 第3个常量池
00 03
interfaces_count u2
# 0个接口
00 00
interfaces u2
Each value in the interfaces
array must be a valid index into the constant_pool
table. The constant_pool
entry at each value of interfaces[i]
, where 0 ≤ i < interfaces_count
, must be a CONSTANT_Class_info
structure representing an interface that is a direct superinterface of this class or interface type, in the left-to-right order given in the source for the type.
u2 interfaces[interfaces_count];
没有实现任何接口,所以interfaces_count=0,这时候也就没有interfaces[]了
fields_count u2
# 2个field
00 02
fields[]
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
field[0]
field[0] - access_flags - u2
private
ACC_PRIVATE | 0x0002 | Declared private ; usable only within the defining class. |
# private
00 02
field[0] - name_index - u2
id
# 常量池第4个位置
00 04
field[0] - descriptor_index - u2
# 常量池第5个位置 是J 是long类型
00 05
field[0] - attributes_count - u2
# 0个attributes_count
00 00
field[0] - attribute_info attributes[attributes_count]
由于上面是0,这里不占空间
field[1]
field[1] - access_flags - u2
public
ACC_PUBLIC | 0x0001 | Declared public ; may be accessed from outside its package. |
# public
00 01
field[1] - name_index - u2
name
# 常量池第6个位置
00 06
field[1] - descriptor_index - u2
L ClassName ; | reference | an instance of class ClassName |
# 常量池第7个位置 是Ljava/lang/String;类型
00 07
field[1] - attributes_count - u2
# 0个attributes_count
00 00
field[1] - attribute_info attributes[attributes_count]
由于上面是0,这里不占空间
methods_count
# 1个方法
00 01
method
method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
method[0] - access_flags u2
public
ACC_PUBLIC | 0x0001 | Declared public ; may be accessed from outside its package. |
# public
00 01
method[0] - name_index u2
# 第8个位置
00 08
method[0] - descriptor_index u2
# 常量池第9个位置
00 09
method[0] - attributes_count u2
# attributes_count有1个
00 01
method[0] - attributes
attribute_info {
u2 attribute_name_index;
u4 attribute_length;
u1 info[attribute_length];
}
method[0] - attributes - attribute_name_index - u2
# 常量池第10个位置 Code
00 0A
method[0] - attributes - attribute_length - u4
# length = 32+15 = 47
00 00 00 2F
Code_attribute
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length; # 指令长度是多少 假设是5 往后数5个字节
u1 code[code_length]; # 2A B7 00 01 B1
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
method[0] - attributes - info[attribute_length]
# 47
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00
00 02 00 0B 00 00 00 06 00 01 00 00 00 08 00 0C
00 00 00 0C 00 01 00 00 00 05 00 0D 00 0E 00 00
attribute_length项的值表示属性的长度,不包括前六个字节(不包括attribute_name_index、attribute_length),也就是从max_stack开始
max_stack = 00 01 = 1
max_locals = 00 01 = 1
u4 code_length = 00 00 00 05 = 5
code[code_length] = 2A B7 00 01 B1
aload_0 = 42 (0x2a)
invokespecial = 183 (0xb7) # 后面2位是操作那个对象
00 01 #1 <java/lang/Object.<init>>
return = 177 (0xb1)
method - exception_table_length - u2
# 0个exception
00 00
attributes_count
# 2个
00 02
LineNumberTable
attributes - attribute_name_index - u2
# LineNumberTable
00 0B
LineNumberTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 line_number_table_length; # 有下面这样的几组
{ u2 start_pc; # 指令码的行数
u2 line_number; # 源码的行号
} line_number_table[line_number_table_length];
}
# attribute_length
00 00 00 06
# 00 01 1组
line_number_table_length
# start_pc 0
00 00
# line_number 8
00 08
LocalVariableTable
# 12
00 0C
LocalVariableTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 local_variable_table_length;
{ u2 start_pc;
u2 length;
u2 name_index;
u2 descriptor_index;
u2 index;
} local_variable_table[local_variable_table_length];
}
attribute_length
# 12
00 00 00 0C
00 01 00 00 00 05 00 0D 00 0E 00 00
local_variable_table_length = 00 01 = 1
u2 start_pc = 00 00 = 0
u2 length = 00 05 = 5
u2 name_index = 00 0D = #13 = this
u2 descriptor_index = 00 0E = #14 = Lcom/kq/jvm/SimpleDemo;
u2 index = 00 00
class - attributes_count - u2
# 1个
00 01
class - attribute_info
attribute_info {
u2 attribute_name_index; # 00 0F = 15
u4 attribute_length; # 00 00 00 02 2字节
u1 info[attribute_length]; # 00 10 = 16
}