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 {
public 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.
来源:https://stackoverflow.com/questions/5546280/understanding-javaps-output-for-the-constant-pool