2012-04-05 12 views
1

Schritt 1: Ich habe folgende Code kompiliert:Warum gibt es einen Eintrag in LocalVariableTable für äußere Klassenobjekt in einer inneren Klasse Konstruktor (Java Bytecode)

public class OuterClass { 
class InnerClass{ 

    } 
} 

ich habe OuterClass.class und OterClass $ InnerClass.class

Schritt2: Ich benutze javap, um den Bytecode der inneren Klasse zu überprüfen. Es ist sehr seltsam, dass die Konstruktormethode "1: aload_1" verwendet, aber in der LocalVariableTable gibt es nur einen Eintrag für "this", auf den aload_0 zugreifen kann. Ich nehme an, dass aload_1 den Pass-In-Parameter - der die Referenz des äußeren Klassenobjekts ist - an den Anfang des Stapels lädt.

Meine Frage: Warum erstellt der Compiler keinen Eintrag dafür (die Referenz der äußeren Klasse, die an den Konstruktor übergeben wird)?

Ich versuchte mit Jsdk 1.4 und openjdk 1.6.

~$ javap -v -c OuterClass\$InnerClass 
Compiled from "OuterClass.java" 
class OuterClass$InnerClass extends java.lang.Object 
    SourceFile: "OuterClass.java" 
    InnerClass: 
    #24= #1 of #22; //InnerClass=class OuterClass$InnerClass of class OuterClass 
    minor version: 0 
    major version: 50 
    Constant pool: 
const #1 = class #2; // OuterClass$InnerClass 
const #2 = Asciz OuterClass$InnerClass; 
const #3 = class #4; // java/lang/Object 
const #4 = Asciz java/lang/Object; 
const #5 = Asciz this$0; 
const #6 = Asciz LOuterClass;; 
const #7 = Asciz <init>; 
const #8 = Asciz (LOuterClass;)V; 
const #9 = Asciz Code; 
const #10 = Field #1.#11; // OuterClass$InnerClass.this$0:LOuterClass; 
const #11 = NameAndType #5:#6;// this$0:LOuterClass; 
const #12 = Method #3.#13; // java/lang/Object."<init>":()V 
const #13 = NameAndType #7:#14;// "<init>":()V 
const #14 = Asciz ()V; 
const #15 = Asciz LineNumberTable; 
const #16 = Asciz LocalVariableTable; 
const #17 = Asciz this; 
const #18 = Asciz LOuterClass$InnerClass;; 
const #19 = Asciz SourceFile; 
const #20 = Asciz OuterClass.java; 
const #21 = Asciz InnerClasses; 
const #22 = class #23; // OuterClass 
const #23 = Asciz OuterClass; 
const #24 = Asciz InnerClass; 

{ 
final OuterClass this$0; 


OuterClass$InnerClass(OuterClass); 
    Code: 
    Stack=2, Locals=2, Args_size=2 
    0: aload_0 
    1: aload_1 
    2: putfield #10; //Field this$0:LOuterClass; 
    5: aload_0 
    6: invokespecial #12; //Method java/lang/Object."<init>":()V 
    9: return 
    LineNumberTable: 
    line 3: 0 

    LocalVariableTable: 
    Start Length Slot Name Signature 
    0  10  0 this  LOuterClass$InnerClass; 


} 

Antwort

0

Ich denke, es ist nur, weil es keinen Eintrag in der lokalen Variablentabelle benötigt, ein Argument sein, das nie als Argument in irgendeiner anderen Art und Weise Bezug genommen zu werden braucht.

1

Die LocalVariableTable ist rein für Debugging-Zwecke - es hat keine Auswirkungen auf die Ausführung. Daher enthält es nur die sichtbaren Quellvariablen, da der Debugger daran interessiert ist. Es gibt keinen Grund, Compiler-generierte Variablen einzubeziehen.