If you look in the
bin directory of a regular Java2 SDK installation, you'll find a 'javap' application (
javap.exe), which you can use as a disassembler by adding the
-c command-line option. This allows you to view the bytecode inside a Java class. A Java class consists of assembly-code-like instructions to the Java virtual machine. For example, consider the following code:
class HelloWorldClass
{
public static void main (String args[])
{
System.out.println ("Hello, world!!!");
}
}
Executing
javap -c HelloWorldClass gives the following output:
Compiled from "HelloWorldClass.java"
class HelloWorldClass extends java.lang.Object{
HelloWorldClass();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()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 Hello, world!!!
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
Viewing the bytecode of a particular class can give you a lot of info about its core internals. For example, consider the following common string concatenation method:
public String strCat (String one, String two)
{
return (one + two);
}
Disassembling this results in the following bytecode:
public java.lang.String strCat(java.lang.String,java.lang.String);
Code:
0: new #7; //class StringBuffer
3: dup
4: invokespecial #8; //Method java/lang/StringBuffer."<init>":()V
7: aload_1
8: invokevirtual #9; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)
Ljava/lang/StringBuffer;
11: aload_2
12: invokevirtual #9; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)
Ljava/lang/StringBuffer;
15: invokevirtual #10; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
18: areturn
The preceding code proves that strings are immutable; therefore you should always perform string concatenation using a StringBuffer rather than simply concatenating strings.