Java Programming/Byte Code

Java Byte Code is the language to which Java source is compiled and the Java Virtual Machine understands. Unlike compiled languages that have to be specifically compiled for each different type of computers, a Java program only needs to be converted to byte code once, after which it can run on any platform for which a Java Virtual Machine exists.

Bytecode is the compiled format for Java programs. Once a Java program has been converted to bytecode, it can be transferred across a network and executed by Java Virtual Machine (JVM). Bytecode files generally have a .class extension. It is not normally necessary for a Java programmer to know byte code, but it can be useful.

Other Languages
There are a number of exciting new languages being created that also compile to Java byte code, such as Groovy.


 * GNAT : The GNU Ada-Compiler, is capable of compiling Ada into Java-style bytecode.
 * ftp://cs.nyu.edu/pub/gnat


 * JPython : Compiles Python to Java-style bytecode.
 * http://www.jpython.org/


 * Kawa : Compiles Scheme to Java-style bytecode.
 * http://www.gnu.org/software/kawa/

Example
Consider the following Java code.

A Java compiler might translate the Java code above into byte code as follows, assuming the above was put in a method:

Example 2
As an example we can write a simple Foo.java source:

Compile it and then move Foo.java to another directory or delete it if you wish. What can we do with javap and Foo.class ?

$javap Foo

produces this result:

Compiled from "Foo.java" public class Foo extends java.lang.Object { public Foo; public static void main(java.lang.String[]); public static void a; public static void b; }

As you can see the javac compiler doesn't strip any (public) variable name from the .class file. As a result the names of the functions, their parameters and types of return are exposed. (This is necessary in order for other classes to access them.)

Let's do a bit more, try:

$javap -c Foo

Compiled from "Foo.java" public class Foo extends java.lang.Object{ public Foo; Code: 0:  aload_0 1:  invokespecial   #1; //Method java/lang/Object." ":V 4:  return

public static void main(java.lang.String[]); Code: 0:  getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3:  ldc             #3; //String This is a simple example of decompilation using javap 5:  invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8:  invokestatic    #5; //Method a:V 11: invokestatic    #6; //Method b:V 14: return

public static void a; Code: 0:  getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3:  ldc             #7; //String Now we are calling a function... 5:  invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8:  return

public static void b; Code: 0:  getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3:  ldc             #8; //String ...and now we are calling b   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8:  return

}

The Java bytecodes
See Oracle's Java Virtual Machine Specification for more detailed descriptions

The manipulation of the operand stack is notated as [before]→[after], where [before] is the stack before the instruction is executed and [after] is the stack after the instruction is executed. A stack with the element 'b' on the top and element 'a' just after the top element is denoted 'a,b'.