AllJava

Understanding Byte Code in Java

[Q] So, what is Java Bytecode ?
[A] Bytecode is the heart of Java portability. Each Java program you write is first converted to a .class file (bytecode), which is then interpreted by Java interpreter.
Few days before I came to an interesting post, which provided a sample code in Java byte code format. Interestingly decoding the code to Java was no big deal as plenty of tools are available like JAD.
But it sparked something more than just the sample code, why is byte code important and why must a Java guy know that ?

Ok! So when you actually compile your code to a class file, Java will not just convert your code into bytecode, there is a lots of optimizations and changes before your code qualifies to be a byte code.
Coming back to the point, why do I need to know about Java Byte Code ?
Have you ever read somewhere the difference between Vector and ArrayList, or why to use StringBuilder against StringBuffer. Have you ever verified the truth ? ūüėÄ
Also once you are capable of reading a byte code, you can also get to know how to optimize your code, what works better and how can you make things better. ūüėČ
So instead of moving directly reading byte code in notepad, I would recommend you a better solution that can not only read your byte code but also provide you a lots of information about your code, including even stacks and memory required to save the state.
Lets create a simple Hello.java with customary Hello World! App.

public class Hello
{
public static void main(String[] ms)
{
System.out.println("Hello World !");
}
}

Now go to command prompt jdk1.x.x/bin. Now execute ->

javap Hello

This will print the skeleton of your Java code. Note that javap uses your class file not your java file.
Enjoyed it ? Now use the below options –

javap -c Hello

 

Compiled from "Hello.java"
public class Hello extends java.lang.Object{
public Hello();
Code:
0:   aload_0
1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
4:   return
public static void mail(java.lang.String[]);
Code:
0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3:   ldc     #3; //String Hello World!
5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
8:   return
}

Observe the String value printed in comments. -c option actually dissembles you class file into fragments.
If you have came upto this line I would recommend you to next use

javap -c -verbose Hello

This will print the stack sizes, number of variables created and other in depth info. Below is the sample run of the command.

Compiled from "Hello.java"
public class Hello extends java.lang.Object
SourceFile: "Hello.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method       #6.#15; //  java/lang/Object."<init>":()V
const #2 = Field        #16.#17;        //  java/lang/System.out:Ljava/io/PrintS
tream;
const #3 = String       #18;    //  Supal Dubey! [http://cubestack.in
]
const #4 = Method       #19.#20;        //  java/io/PrintStream.println:(Ljava/l
ang/String;)V
const #5 = class        #21;    //  Hello
const #6 = class        #22;    //  java/lang/Object
const #7 = Asciz        <init>;
const #8 = Asciz        ()V;
const #9 = Asciz        Code;
const #10 = Asciz       LineNumberTable;
const #11 = Asciz       mail;
const #12 = Asciz       ([Ljava/lang/String;)V;
const #13 = Asciz       SourceFile;
const #14 = Asciz       Hello.java;
const #15 = NameAndType #7:#8;//  "<init>":()V
const #16 = class       #23;    //  java/lang/System
const #17 = NameAndType #24:#25;//  out:Ljava/io/PrintStream;
const #18 = Asciz       Supal Dubey! [http://cubestack.in];
const #19 = class       #26;    //  java/io/PrintStream
const #20 = NameAndType #27:#28;//  println:(Ljava/lang/String;)V
const #21 = Asciz       Hello;
const #22 = Asciz       java/lang/Object;
const #23 = Asciz       java/lang/System;
const #24 = Asciz       out;
const #25 = Asciz       Ljava/io/PrintStream;;
const #26 = Asciz       java/io/PrintStream;
const #27 = Asciz       println;
const #28 = Asciz       (Ljava/lang/String;)V;
{
public Hello();
Code:
Stack=1, Locals=1, Args_size=1
0:   aload_0
1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
4:   return
LineNumberTable:
line 1: 0
public static void mail(java.lang.String[]);
Code:
Stack=2, Locals=1, Args_size=1
0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3:   ldc     #3; //String Supal Dubey! [http://cubestack.in]
5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
8:   return
LineNumberTable:
line 5: 0
line 6: 8
}

You can play around with javap using

 javap -help 

Leave a comment in case you need more info on this topics.

One thought on “Understanding Byte Code in Java

Leave a Reply

Your email address will not be published. Required fields are marked *