开发者

Understanding javap's output for the Constant Pool

When running javap on a very simple HelloWorld application I have some confusion on the output around the constant pool.

Test Code

public class TestClass {
    publi开发者_如何学Pythonc static void main(String[] args) {
        System.out.println("hello world");
    }
}

Javap -c -verbose output (snipped)

// Header + consts 1..22 snipped
const #22 = String      #23;    //  hello world
const #23 = Asciz       hello world;

public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc     #22; //String hello world
   5:   invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return
  // Debug info snipped
}

Ok, so on line 3 we see a pushing of the "hello world" constant onto the stack via #22, but const #23 seems to hold the actual value. I guess I am a little confused with what the #(number) means when it appears on the right-hand-side of the printout.

Oracle/Sun's man page for javap leaves much to be desired.


All your class, interface, field names and string constants go into the java constant pool.

As per VM Spec ( http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html ):

The constant_pool is a table of structures (§4.4) representing various string constants, class and interface names, field names, and other constants that are referred to within the ClassFile structure and its substructures. The format of each constant_pool table entry is indicated by its first "tag" byte. The constant_pool table is indexed from 1 to constant_pool_count-1.

So in terms of constant pool something like below can be viewed as:

const #22 = String      #23;    //  hello world
const #23 = Asciz       hello world;

The value at #22 (index 22) is of type String and its value is null terminated c string (Asciz) hello world is at index 23.


The Java constant pool stores two different kinds of entries when storing a string. First, it stores the string literal as UTF-8 encoded data (here, constant #23). Second, it also stores an string entry (#22) indicating that the contents of constant #23 should be used to construct a String. I think the reason for this is that the JVM associates with each class a "runtime constant pool" consisting of a dynamic implementation of the given constants. For strings, this can be a reference to the interned String object holding the given characters. UTF-8 constant data has other uses besides string literals (for example, naming fields and classes), so this extra indirection seems like a reasonable way to separate out the concerns.


Pool entry #22 is a java.lang.String object. Entry #23 is the array of characters used to construct that String.

The Java VM Spec is the "missing manual" for javap.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜