2015-01-31 5 views
9

Dies ist der Quellcode ich habe:Wann und wo wird der String im Java-Quellcode initialisiert/gespeichert?

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

Und wenn ich diese kompilieren, erhalte ich die Bytecode. Als ich bei der Bytecode mit einem Hexadezimal-Viewer betrachten sehe ich Teil:

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 

die als

gelesen werden kann
This is a sample program. 

wenn der Bytes als Zeichen interpretiert werden.

Und wenn ich

javap -c Koray.class 

diese Klasse zerlegen ich sehe:

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   
} 

Meine Frage ist, wo ist dieser String im demontierten Text gesehen? Ich sehe es nur in einem Kommentar.

Antwort

4

Sehen Sie, dass ldcinstruction? Es lädt eine Konstante aus dem Laufzeitkonstantenpool. Dort wird die Zeichenfolge gespeichert. Um auch den Konstantenpool zu drucken, fügen Sie -verboseoption zu javap call hinzu.

+0

Können wir sagen, dass wir keine Zeichenfolgen im Quellcode verwenden sollten, weil es den Speicher füllt, wenn die Klasse geladen wird und nie aus dem entfernt wird Speicher, weil es im konstanten Pool ist? –

+0

@KorayTugay keine Sorge, _interned_ Strings (und alle String-Literale sind _interned_) werden seit JDK7 im Heap gespeichert. –

+0

@KorayTugay Verwenden Sie diese im Quellcode, wenn sie den Code klarer machen als etwas anderes. Der Speicherbedarf von String-Konstanten ist vernachlässigbar. – chrylis

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

Diese Linie verwendet den opcodeldc, die eine konstante, auf dem Operandenstapel lädt. An dieser Stelle laden wir die Konstante, die sich im Index #3 unserer Konstant-Pool-Tabelle befindet.

In der Konstant-Pool-Tabelle werden die meisten literalen Konstantenwerte gespeichert. (ref) Der Befehl javap -c -verbose <classfile> liefert die Ausgabe für die konstante Pool-Tabelle.

Beispiel Ausgang:

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

Weitere Daten von VM Spec (http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html):

Die constant_pool ist eine Tabelle der Strukturen (§4.4) verschiedene String-Konstanten, die Klasse und Schnittstelle repräsentierten Namen, Feldnamen und andere Konstanten, auf die innerhalb der ClassFile-Struktur und ihrer Unterstrukturen verwiesen wird. Das Format jedes Eintrags der Tabelle constant_pool ist , angezeigt durch sein erstes "Tag" -Byte. Die Tabelle "constant_pool" wird von 1 bis "constant_pool_count-1" mit indiziert.

+0

Aber was ist in Index 3? –

+0

'Index 3' ist der Index in der Tabelle. –

+0

Welchen Tisch, können Sie genauer sein? –

4

ldc #3 lädt die String-Konstante in dem Konstanten-Pool gespeichert, die eine separate Tabelle, die Konstanten wie String Literale und Klassennamen speichert.

Siehe http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4 von der JVM-Spezifikation:

Die constant_pool ist eine Tabelle der Strukturen (§4.4) verschiedene String-Konstanten repräsentieren, die Klasse und Schnittstellennamen, Feldnamen und andere Konstanten, die innerhalb der bezeichnet werden ClassFile-Struktur und ihre Unterstrukturen. Das Format jedes Eintrags der Tabelle constant_pool wird durch sein erstes Tag-Byte angezeigt.

Sie können die String-Tabelle mit javap -verbose ClassName anzeigen.

Ein Beispiel für die Ausgabe wäre so etwas wie:

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. 
...