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."":()V 4: returnpublic 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."":()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.