In this post, we will explore the inner parts of a class file going byte by byte!!
The class file format is defined at https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html. It says:
Each
class
file contains the definition of a single class or interface.
I will add that the class may be public or package-private. For instance, it is possible to have a java file like:
public class MyClass { } class OtherClass{ } interface MyInterface{ }
The only constraint enforced by the compiler is that the name of the java file matches the name of the public class/interface defined inside the java file.
After compiling MyClass.java, three class files are generated:
javac -g -d myclasses/ src/main/java/fjab/MyClass.javaz ls -l myclasses/fjab/ MyClass.class MyInterface.class OtherClass.class
In the rest of this post, we will study the bytecode representation of MyClass.
So what does a class file look like? According to the JVM specification
A
class
file consists of a stream of 8-bit bytes.
Simple enough. How to see the stream of bytes corresponding to MyClass.class? This class reads the class from the class path and prints out the stream of bytes in hexadecimal format (for clarity’s sake, the bytes are separated by a blank space):
import java.io.InputStream; public class Main { public static void main(String[] args) throws Exception { InputStream is = Main.class.getClassLoader().getResourceAsStream("fjab/MyClass.class"); int i; int count = 0; while((i=is.read())!=-1){ count++; //System.out.print(i+" "); System.out.print(Integer.toHexString(i)+" "); //System.out.print((char)i+" "); } System.out.print("\nsize in bytes:" +count); } }
To run the class it is necessary to include the dependency on commons-io-1.3.2.jar:
java -cp /Users/franciscoalvarez/.m2/repository/commons-io/commons-io/1.3.2/commons-io-1.3.2.jar:myclasses/ fjab.Main ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c size in bytes:256
To help us decode the stream of bytes, let’s run again the program to print out the stream of bytes in decimal format by commenting out
System.out.print(Integer.toHexString(i)+" ");
and uncommenting
//System.out.print(i+" ");
The result is
java -cp /Users/franciscoalvarez/.m2/repository/commons-io/commons-io/1.3.2/commons-io-1.3.2.jar:myclasses/ fjab.Main 202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12 size in bytes:256
According to the JVM specification, the first 4 bytes represent the magic number identifying the class
file format:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Then there is the minor and major version numbers of this class
file (two bytes long each):
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
To help us confirm this data, we can get another representation of the class file, the one given by javap:
javap -v myclasses/fjab/MyClass.class Classfile /Users/franciscoalvarez/MyProjects/asm/myclasses/fjab/MyClass.class
Last modified 19-Jan-2016; size 256 bytes
MD5 checksum aec828aa514f3431310ff093a1d8bacc
Compiled from "MyClass.java"
public class fjab.MyClass
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#13 // java/lang/Object."<init>":()V
#2 = Class #14 // fjab/MyClass
#3 = Class #15 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lfjab/MyClass;
#11 = Utf8 SourceFile
#12 = Utf8 MyClass.java
#13 = NameAndType #4:#5 // "<init>":()V
#14 = Utf8 fjab/MyClass
#15 = Utf8 java/lang/Object
{
public fjab.MyClass();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lfjab/MyClass;
}
SourceFile: "MyClass.java"
The next 2 bytes are the number of entries in the constant_pool
table plus one (constant_pool_count). According to the result given by javap, constant_pool_count must be 16
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next is the constant pool representing various string constants, class and interface names, field names, and other constants that are referred to within the class. The format of constant_pool
table entries is explained at https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4
First entry in the constant pool is
#1 = Methodref #3.#13 // java/lang/Object."<init>":()V
that corresponds to the following, where 10 is the value of CONSTANT_Methodref, 3 is an index into the constant_pool
table whose entry entry must be a CONSTANT_Class_info structure and 13 is an index into the constant_pool
table whose entry entry must be a CONSTANT_NameAndType_info structure. In a nutshell, the first entry in the constant pool represents the constructor of java.lang.Object and its descriptor.
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Second entry in the constant pool represents the class fjab.MyClass
#2 = Class #14 // fjab/MyClass
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Third entry represents the class java.lang.Object
#3 = Class #15 // java/lang/Object
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Fourth entry is the literal <init>, where 1 represents CONSTANT_Utf8_info, the next 2 bytes represent the length of the string, in this case 6. The next 6 bytes represent the characters of the string.
#4 = Utf8 <init>
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next entry is the literal ()V, 3 bytes long
#5 = Utf8 ()V
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next entry is the literal Code, 4 bytes long
#6 = Utf8 Code
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next is the literal LineNumberTable, 15 bytes long
#7 = Utf8 LineNumberTable
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next is the literal LocalVariableTable, 18 bytes long
#8 = Utf8 LocalVariableTable
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next is the literal this, 4 bytes long
#9 = Utf8 this
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next is the literal Lfjab/MyClass;, 14 bytes long
#10 = Utf8 Lfjab/MyClass;
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next entry is the literal SourceFile, 10 bytes long
#11 = Utf8 SourceFile
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Then is the literal MyClass.java, 12 bytes long
#12 = Utf8 MyClass.java
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
Next entry is a CONSTANT_NameAndType_info
structure used to represent a field or method, without indicating which class or interface type it belongs to. In this case, it is a constructor without arguments
#13 = NameAndType #4:#5 // "<init>":()V
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
where the first byte (12) is the tag
item of the CONSTANT_NameAndType_info
structure, the next 2 bytes are a valid index into the constant_pool
table pointing to the entry of the constant pool table that contains the name of the method and the final 2 bytes are a valid index into the constant_pool
table pointing to the entry of the constant pool table that contains the descriptor of the method.
Next entry is another UTF8 constant, fjab/MyClass, 12 bytes long
#14 = Utf8 fjab/MyClass
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
The final entry of the constant pool table is the literal java/lang/Object, 16 bytes long
#15 = Utf8 java/lang/Object
202 254 186 190 0 0 0 52 0 16 10 0 3 0 13 7 0 14 7 0 15 1 0 6 60 105 110 105 116 62 1 0 3 40 41 86 1 0 4 67 111 100 101 1 0 15 76 105 110 101 78 117 109 98 101 114 84 97 98 108 101 1 0 18 76 111 99 97 108 86 97 114 105 97 98 108 101 84 97 98 108 101 1 0 4 116 104 105 115 1 0 14 76 102 106 97 98 47 77 121 67 108 97 115 115 59 1 0 10 83 111 117 114 99 101 70 105 108 101 1 0 12 77 121 67 108 97 115 115 46 106 97 118 97 12 0 4 0 5 1 0 12 102 106 97 98 47 77 121 67 108 97 115 115 1 0 16 106 97 118 97 47 108 97 110 103 47 79 98 106 101 99 116 0 33 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 47 0 1 0 1 0 0 0 5 42 183 0 1 177 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 12 0 1 0 0 0 5 0 9 0 10 0 0 0 1 0 11 0 0 0 2 0 12
The next 2 bytes are the access flags of the class and, according to https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.1-200-E.1, the flags are ACC_PUBLIC+ACC_SUPER (0x0001+0x0020)
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
javap -v myclasses/fjab/MyClass.class Classfile /Users/franciscoalvarez/MyProjects/asm/myclasses/fjab/MyClass.class
Last modified 19-Jan-2016; size 256 bytes
MD5 checksum aec828aa514f3431310ff093a1d8bacc
Compiled from "MyClass.java"
public class fjab.MyClass
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#13 // java/lang/Object."<init>":()V
#2 = Class #14 // fjab/MyClass
#3 = Class #15 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lfjab/MyClass;
#11 = Utf8 SourceFile
#12 = Utf8 MyClass.java
#13 = NameAndType #4:#5 // "<init>":()V
#14 = Utf8 fjab/MyClass
#15 = Utf8 java/lang/Object
{
public fjab.MyClass();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lfjab/MyClass;
}
SourceFile: "MyClass.java"
Next 2 bytes represent this class, it must be a valid index into the constant_pool
table pointing to a CONSTANT_Class_info
structure representing the class defined by this class
file. After taking a look at the constant pool table, it is clear that the wanted index is #2, fjab/MyClass:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes represent the super class, it must be a valid index into the constant_pool
table pointing to a CONSTANT_Class_info
structure representing the direct superclass of the class defined by this class
file. After taking a look at the constant pool table, it is clear that the wanted index is #3, java/lang/Object:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Nex 2 bytes are the number of direct superinterfaces of this class, in this case 0:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Nex 2 bytes are the number of all fields, both class variables and instance variables, declared by this class, in this case 0:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Nex 2 bytes are the number of all methods declared by this class, including instance methods, class methods, instance initialization methods, and any class or interface initialization method. It does not include items representing methods that are inherited from superclasses or superinterfaces. In this case, there is just 1 method, the constructor
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next is the method_info
structure representing the method according to https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6. The first 2 bytes is the value of the access_flags
item, in this case ACC_PUBLIC (0x0001)
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Then there are 2 bytes representing an index into the constant_pool
table pointing to the name of the method. In this case the wanted index is #4, <init>
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes represent an index into the constant_pool
table pointing to the descriptor of the method. In this case the wanted index is #5, ()V
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes represent the number of additional attributes of this method.
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next is the attribute_info
structure, defined by https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.
First 2 bytes is an index into the constant pool of the class pointing to the name of the attribute. In this case, the wanted index is #6, that contains the literal “Code”. Therefore, this attribute corresponds to the code of the constructor.
According to JVM specification, if the method is either native
or abstract
, its method_info
structure must not have a Code
attribute in its attributes
table. Otherwise, its method_info
structure must have exactly one Code
attribute in its attributes
table
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 4 bytes indicate the length of the subsequent information in bytes, 0x2f or 47:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
The Code_attribute
structure is defined by https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3.
Next 2 bytes represent the maximum depth of the operand stack of this method, in this case 1:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes represent the number of local variables in the local variable array allocated upon invocation of this method, in this case 1 (the object itself):
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 4 bytes is the actual number of bytes of Java Virtual Machine code that implement the method. This value must be greater than zero (as the code
array must not be empty) and less than 65536 (so yes, there is a limit to the size of a Java method!). In this case, the implementation of the constructor takes 5 bytes:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next is the array of instructions that implement the method:
1. 0x2a (whose nemonic is aload_0)
2. 0xb7 (invokespecial)
3,4. positions 3 and 4 are the argument of the instruction invokespecial and correspond to a 2-byte value containing an index of the constant pool table, in this case #1. Remember that the first element of the constant pool is the constructor of java/lang/Object.
5. the last instruction is 0xb1 (return)
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes represent the number of exception handlers of this method, in this case is 0:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes indicate the number of attributes of the Code
attribute, in this case 2:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes represent the index of the constant pool pointing to the name of the first Code attribute, #7, LineNumberTable, which is defined by https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.12. This attribute may be used by debuggers to determine which instruction of the method corresponds to a given line number in the original source file.
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Then there are 4 bytes to specify the length of the attribute, in this case 6 bytes:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes indicate the number of entries in the line_number_table
array, in this case 1:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
javap -v myclasses/fjab/MyClass.class Classfile /Users/franciscoalvarez/MyProjects/asm/myclasses/fjab/MyClass.class
Last modified 19-Jan-2016; size 256 bytes
MD5 checksum aec828aa514f3431310ff093a1d8bacc
Compiled from "MyClass.java"
public class fjab.MyClass
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#13 // java/lang/Object."<init>":()V
#2 = Class #14 // fjab/MyClass
#3 = Class #15 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lfjab/MyClass;
#11 = Utf8 SourceFile
#12 = Utf8 MyClass.java
#13 = NameAndType #4:#5 // "<init>":()V
#14 = Utf8 fjab/MyClass
#15 = Utf8 java/lang/Object
{
public fjab.MyClass();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lfjab/MyClass;
}
SourceFile: "MyClass.java"
Each entry in the line_number_table
array indicates the opcode instruction to which a line in the source code relates.
Next 2 bytes must indicate the index into the code
array at which the code for a new line in the original source file begins, in this case 0
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes must give the corresponding line number in the original source file, in this case 6:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes represent the index of the constant pool pointing to the name of the second Code attribute, #8, LocalVariableTable, which is defined by https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.13. This attribute may be used by debuggers to determine the value of a given local variable during the execution of a method.
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Then there are 4 bytes to specify the length of the attribute, in this case 12 bytes (0xc):
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes indicate the number of entries in the local_variable_table
array, in this case 1:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
javap -v myclasses/fjab/MyClass.class Classfile /Users/franciscoalvarez/MyProjects/asm/myclasses/fjab/MyClass.class
Last modified 19-Jan-2016; size 256 bytes
MD5 checksum aec828aa514f3431310ff093a1d8bacc
Compiled from "MyClass.java"
public class fjab.MyClass
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#13 // java/lang/Object."<init>":()V
#2 = Class #14 // fjab/MyClass
#3 = Class #15 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lfjab/MyClass;
#11 = Utf8 SourceFile
#12 = Utf8 MyClass.java
#13 = NameAndType #4:#5 // "<init>":()V
#14 = Utf8 fjab/MyClass
#15 = Utf8 java/lang/Object
{
public fjab.MyClass();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lfjab/MyClass;
}
SourceFile: "MyClass.java"
The local_variable_table
array indicates a range of code
array offsets within which a local variable has a value. It also indicates the index into the local variable array of the current frame at which that local variable can be found. So the local variable “this” has a value in the entire method (as the method implementation has 5 instructions) and is stored in the first slot of the local variable array.
Next 2 bytes is the index of the opcode of the first instruction where the variable has a value.
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes is the number of instructions during which the variable has a value:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes must be a valid index into the constant_pool
table pointing to the name of the variable. In this case, the wanted index is #9, whose value is “this”
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes must be a valid index into the constant_pool
table pointing to the descriptor of the variable. In this case, the wanted index is #10 (0xa), whose value is Lfjab/MyClass;
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes is the index occupied by the local variable in the local variable array of the current frame, in this case it is 0
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
All the method info is over.
Next 2 bytes indicates the number of attributes of the class, in this case it is 1:
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 2 bytes must be an index into the constant pool of the class pointing to the name of the attribute. In this case is 11 (0xb) that is “SourceFile”, that is defined by https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.10
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Next 4 bytes is the number of bytes of this attribute, that is always 2 for “SourceFile”.
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
Last 2 bytes of the class file are an index into the constant_pool
table pointing to the name of the attribute, that is, the name of the source file. In this case, the wanted index is 12 (0xc):
ca fe ba be 0 0 0 34 0 10 a 0 3 0 d 7 0 e 7 0 f 1 0 6 3c 69 6e 69 74 3e 1 0 3 28 29 56 1 0 4 43 6f 64 65 1 0 f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 1 0 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 1 0 4 74 68 69 73 1 0 e 4c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 3b 1 0 a 53 6f 75 72 63 65 46 69 6c 65 1 0 c 4d 79 43 6c 61 73 73 2e 6a 61 76 61 c 0 4 0 5 1 0 c 66 6a 61 62 2f 4d 79 43 6c 61 73 73 1 0 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 0 21 0 2 0 3 0 0 0 0 0 1 0 1 0 4 0 5 0 1 0 6 0 0 0 2f 0 1 0 1 0 0 0 5 2a b7 0 1 b1 0 0 0 2 0 7 0 0 0 6 0 1 0 0 0 6 0 8 0 0 0 c 0 1 0 0 0 5 0 9 0 a 0 0 0 1 0 b 0 0 0 2 0 c
At last!! We have covered the entire bytecode. Even the simplest of the Java classes has taken this long to be described in terms of bytecode.