2015-01-31 13 views
9

Questo è il codice sorgente che ho:Quando e dove viene inizializzata/memorizzata la stringa nel codice sorgente Java?

public class Koray { 
    public static void main(String [] args) { 
      System.out.println("This is a sample program."); 
    } 
} 

E quando compilo questo, ottengo il bytecode. Quando guardo il bytecode con un visualizzatore esadecimale vedo parte:

19 54 68 69 73 20 69 73 20 61 20 73 61 6D 70 6C 65 20 70 72 6F 67 72 61 6D 2E 

che può essere letto come

This is a sample program. 

se i byte vengono interpretati come caratteri.

E quando lo faccio

javap -c Koray.class 

non smontare questa classe vedo:

Compiled from "Koray.java" 
public class Koray { 
    public Koray(); 
    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 This is a sample program. 
     5: invokevirtual #4     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     8: bipush  10 
     10: istore_1  
     11: return   
} 

La mia domanda è, dove è questo String visto nel testo smontato? Lo vedo solo in un commento.

risposta

4

Vedi che ldcinstruction? Carica una costante dal pool costante di runtime. Ecco dove viene archiviata la tua stringa. Per stampare anche il pool costante, aggiungere -verboseoption alla chiamata javap.

+0

Possiamo dire che non dovremmo usare le stringhe nel codice sorgente perché riempirà la memoria quando la classe viene caricata e non verrà mai rimossa dal memoria perché è nella piscina costante? –

+0

@KorayTugay non ti preoccupare, _interned_ Strings (e tutti i letterali delle stringhe sono _interned_) sono archiviati nell'heap sin da JDK7. –

+0

@KorayTugay Usale nel codice sorgente se rende il codice più chiaro di quello che fa qualcos'altro. Il sovraccarico della memoria delle costanti di stringa è trascurabile. – chrylis

4
ldC#3; //String This is a sample program. 

Questa linea utilizza il opcodeldc, che carica una costante nello stack operando. A questo punto, andremo a caricare qualsiasi costante nell'indice #3 della nostra tabella di biliardo costante.

La tabella di biliardo costante contiene la maggior parte dei valori costanti letterali. (ref) Il comando javap -c -verbose <classfile> fornisce l'output per la tabella di pool costante. uscita

Esempio:

const #22 = String  #23; // This is a sample program 
const #23 = Asciz  This is a sample program; 

Maggiori informazioni del VM Spec (http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html):

Il constant_pool è una tabella di strutture (§ 4.4) rappresentano le varie costanti di stringa, classe e l'interfaccia nomi, nomi dei campi e altre costanti a cui si fa riferimento all'interno della struttura ClassFile e delle sue sottostrutture. Il formato di ogni voce della tabella constant_pool è indicato dal suo primo byte "tag". La tabella constant_pool è indicizzata da da 1 a constant_pool_count-1.

+0

Ma cosa c'è nell'indice 3? –

+0

'Indice 3' è l'indice nella tabella. –

+0

Quale tabella, puoi essere più specifico? –

4

ldc #3 carichi costanti stringa memorizzata nella piscina costante, che è una tabella separata che memorizza le costanti come String letterali ei nomi di classe.

Vedi http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4 dalle specifiche JVM:

Il constant_pool è una tabella di strutture (§ 4.4) che rappresentano varie costanti di stringa, nomi di classe e di interfaccia, nomi di campo, e altre costanti che si fa riferimento ai Struttura ClassFile e sue sottostrutture. Il formato di ogni voce della tabella constant_pool è indicato dal suo primo byte "tag".

È possibile visualizzare la tabella di stringhe utilizzando javap -verbose ClassName.

Un esempio di output sarebbe qualcosa di simile:

Compiled from "Test.java" 
public class tests.Test extends java.lang.Object 
    SourceFile: "Test.java" 
    minor version: 0 
    major version: 50 
    Constant pool: 
const #1 = class  #2;  // tests/Test 
const #2 = Asciz  tests/Test; 
const #3 = String  #4;  // This is a sample program. 
... 
Problemi correlati