2011-04-05 13 views
19

Cuando ejecuto javap en una aplicación HelloWorld muy simple, tengo cierta confusión en la salida alrededor del conjunto constante.Comprender la salida de javap para el conjunto constante

Código de prueba

public class TestClass { 
    public static void main(String[] args) { 
     System.out.println("hello world"); 
    } 
} 

javap -c salida -verbose (cortado con tijeras)

// 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, por lo que en la línea 3 vemos un empuje de la "hola mundo" constante en la pila a través del # 22, pero const # 23 parece contener el valor real. Supongo que estoy un poco confundido con lo que el # (número) significa cuando aparece en el lado derecho de la copia impresa.

Oracle/Sun's man page for javap deja mucho que desear.

Respuesta

22

Toda su class, interface, field nombres y string constantes de entrar en la piscina java constante.

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

El constant_pool es una tabla de estructuras (§4.4) que representan varios constantes de cadena, la clase y la interfaz nombres, nombres de campo, y otros constantes que se hace referencia dentro de la estructura ClassFile y sus subestructuras . El formato de cada entrada de la tabla constant_pool se indica por su primer byte "tag". La tabla constant_pool está indexada desde 1 hasta constant_pool_count-1.

Así que en términos de la piscina constante algo, como a continuación se puede ver como:

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

El valor en el # 22 (índice 22) es de tipo String y su valor es nulo secuencia de c terminado (Asciz) hello world está en el índice 23.

+0

como 'jdk-7' (http://bugs.sun.com/view_bug.do?bug_id=6868539) es' utf8' y no 'asciz' – Eugene

3

Pool entry # 22 es un objeto java.lang.String. La entrada n. ° 23 es la matriz de caracteres utilizada para construir esa cadena.

El Java VM Spec es el "manual faltante" para javap.

5

El pool de constantes de Java almacena dos tipos diferentes de entradas cuando se almacena una cadena. Primero, almacena la cadena literal como datos codificados UTF-8 (aquí, constante # 23). Segundo, también almacena una entrada de cadena (# 22) que indica que el contenido de la constante # 23 se debe usar para construir un String. Creo que la razón para esto es que la JVM asocia con cada clase un "conjunto de constantes de tiempo de ejecución" que consiste en una implementación dinámica de las constantes dadas. Para cadenas, esto puede ser una referencia al objeto interno String que contiene los caracteres dados. Los datos constantes de UTF-8 tienen otros usos además de los literales de cadena (por ejemplo, nombres de campos y clases), por lo que esta indirección adicional parece ser una forma razonable de separar las preocupaciones.