For educational purposes, I decompiled a simple Java class file by hand. I used https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html as a reference.
Last active
April 27, 2016 05:41
-
-
Save aj-michael/d93dc21c1096b1efbbed7cec80c1e067 to your computer and use it in GitHub Desktop.
class file taken apart.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
first 4 bytes: magic number | |
0xCAFEBABE | |
next 2 bytes: minor version | |
0x00 | |
next 2 bytes: major version | |
0x34 = 52 | |
next 2 bytes: constant pool count | |
0x001B = 27 | |
=== cp_info[] === | |
cp info 0x01 = methodref | |
tag: 0x0A = 10 = CONSTANT_Methodref | |
class_index: 0x0005 | |
name_and_type_index: 0x000E | |
cp info 0x02 | |
tag: 0x09 = CONSTANT_Fieldref | |
class_index: 0x000F | |
name_and_type_index: 0x0010 | |
cp info 0x03 | |
tag: 0x0A = 10 = CONSTANT_Methodref | |
class_index: 0x0011 | |
name_and_type_index: 0x0012 | |
cp info 0x04 | |
tag: 0x07 = CONSTANT_Class | |
name_index = 0x0013 | |
cp info 0x05 | |
tag: 07 = CONSTANT_CLASS | |
name_index = 0x0014 | |
cp info 0x06 | |
tag: 01 = CONSTANT_Utf8 | |
length: 0x0006 | |
bytes = 3C 69 6E 69 74 3E = "<init>" | |
cp info 0x07 | |
tag: 01 = Utf8 | |
length = 0x0003 | |
bytes = 28 29 56 = "()V" | |
cp info 0x08 | |
tag: 01 = Utf8 | |
length = 0x0004 | |
bytes = 43 6F 64 65 = "Code" | |
cp info 0x09 | |
tag: 01 = Utf8 | |
length = 0x000F | |
bytes = 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 = "LineNumberTable" | |
cp info 0x0A | |
tag: 01 = Utf8 | |
length = 0x0004 | |
bytes = 6D 61 69 6E = "main" | |
cp info 0x0B | |
tag: 01 = Utf8 | |
length = 0x0016 | |
bytes = 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 = "([Ljava/lang/string;)V" | |
cp info 0x0C | |
tag: 01 | |
length = 0x000A | |
bytes = 53 6F 75 72 63 65 46 69 6C 65 = "SourceFile" | |
cp info 0x0D | |
tag: 01 | |
length = 0x0012 | |
bytes = 74 65 73 74 63 61 73 65 30 30 5F 30 31 2E 6A 61 76 61 = "testcase00_01.java" | |
cp info 0x0E | |
tag: 0x0C = Constant_NameAndType | |
name_index = 0x0006 | |
descriptor_index = 0x0007 | |
cp info 0x0F | |
tag: 0x07 = Constant_Class | |
name_index: 0x0015 | |
cp info 0x10 | |
tag: 0x0C = NameAndType | |
name_index = 0x0016 | |
descriptor_index = 0x0017 | |
cp info 0x11 | |
tag: 0x07 = Class | |
name_index = 0x0018 | |
cp info 0x12 | |
tag: 0x0C = NameAndType | |
name_index = 0x0019 | |
descriptor_index = 0x001A | |
cp info 0x13 | |
tag: 0x01 = Utf8 | |
length = 0x0004 | |
bytes = 4D 61 69 6E = "Main" | |
cp info 0x14 | |
tag: 0x01 | |
length = 0x0010 | |
bytes = 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 = "java/lang/Object" | |
cp info 0x15 | |
tag: 0x01 | |
length = 0x0010 | |
bytes = 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D | |
cp info 0x16 | |
tag: 0x01 | |
length = 0x0003 | |
bytes = 6F 75 74 = "out" | |
cp info 0x17 | |
tag: 0x01 | |
length = 0x0015 | |
bytes = 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B = "Ljava/io/PrintStream;" | |
cp info 0x18 | |
tag: 0x01 | |
length = 0x0013 | |
bytes = 6A 62 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D = "java/io/PrintStream" | |
cp info 0x19 | |
tag: 0x01 | |
length = 0x0007 | |
bytes = 70 72 69 6E 74 6C 6E = "println" | |
cp info 0x1A | |
tag: 0x01 | |
length = 0x0004 | |
bytes = 28 49 29 56 = "(I)V" | |
=== end constant_pool === | |
access_flags = 0x0020 = ACC_SUPER = backwards compat default | |
this_class = 0x0004 | |
super_class = 0x0005 | |
interfaces_count = 0x0000 | |
interfaces = [] | |
fields_count = 0x0000 | |
fields = [] | |
methods_count = 0x0002 | |
=== methods === | |
method 1: | |
access_flags = 0x0000 = none applied? | |
name_index = 0x0006 | |
descriptor_index = 0x0007 | |
attributes_count = 0x0001 | |
=== attributes === | |
attribute_name_index = 0x0008 ("Code") | |
attribute_length = 0x0000001D | |
info = 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 09 00 00 00 06 00 01 00 00 00 01 | |
=== Parsing attribute as a code attribute === | |
attribute_name_index = 0x0008 ("Code") | |
attribute_length = 0x0000001D | |
max_stack = 0x0001 | |
max_locals = 0x0001 | |
code_length = 0x00000005 | |
code = 2A B7 00 01 B1 | |
=== Code breakdown | |
2A = aload_0 | |
// puts this object on stack | |
B7 00 01 = invokespecial 0 1 | |
// 0x0001 is a reference to java.lang.Object constructor. | |
// java.lang.Object constructor is called on the current object. | |
B1 = return void | |
=== | |
exception_table_length = 0x0000 | |
exception_table = [] | |
attributes_count = 0x0001 | |
attributes = [ | |
{ attribute_name_index = 0x0009 ("LineNumberTable") | |
, attribute_length = 0x00000006 | |
, info = 00 01 00 00 00 01 | |
, === parsing attribute as LineNumberTable === | |
attribute_name_index = 0x0009 ("LineNumberTable") | |
attribute_length = 0x00000006 | |
line_number_table_length = 0x0001 | |
line-number_table = [ | |
{ start_pc = 0x0000 | |
, line_number = 0x0001 | |
} | |
] | |
=== end LineNumberTable attribute === | |
} | |
] | |
=== end code attribute === | |
=== end attributes === | |
method2 | |
access_flags = 0x0009 (???) | |
name_index = 0x000A ("main") | |
descriptor_index = 0x000B ("([Ljava/lang/String;)V") | |
attributes_count = 0x0001 | |
attributes = [ | |
{ === parsed as Code === | |
attribute_name_index = 0x0008 ("Code"), | |
attribute_length = 0x00000024, | |
max_stack = 0x0002 | |
max_locals = 0x0001 | |
code_length = 0x00000008 | |
code = B2 00 02 07 B6 00 03 B1 | |
=== Code breakdown | |
getstatic 0 2 | |
// 0x0002 is the reference to "System.out". The System.out reference is put on the stack. | |
iconst_4 // pushes 4 onto stack | |
invokevirtual 0 3 | |
// 0x0003 is the reference to the println function. | |
// This takes the object and the argument 4 off the stack, and calls println with them. | |
return | |
// returns void | |
=== | |
exception_table_length = 0x0000 | |
execption_table = [] | |
attributes_count = 0x0001 | |
attributes = [{ | |
attribute_name_index = 0x0009 ("LineNumberTabl") | |
attribute_length = 0x0000000A | |
line_number_table_length = 0x0002 | |
line_number_table = [ | |
{ start_pc = 0x0000 | |
, line_number = 0x0005 | |
}, | |
{ start_pc = 0x0007 | |
, line_number = 0x0006 | |
} | |
] | |
}] | |
=== end Code === | |
} | |
] | |
=== end methods === | |
attributes_count = 0x0001 | |
attributes = [ | |
{ attribute_name_index = 0x000C ("SourceFile") | |
, attribute_length = 0x00000002 | |
, sourcefile_index = 0x000D | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
˛∫æ4 | |
<init>()VCodeLineNumberTablemain([Ljava/lang/String;)V | |
SourceFiletestcase00_01.javaMainjava/lang/Objectjava/lang/SystemoutLjava/io/PrintStream;java/io/PrintStreamprintln(I)V *∑± | |
$≤∂± | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Main | |
{ | |
public static void main( String[] args ) | |
{ | |
System.out.println(4); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment