简体   繁体   中英

Why isn't there an entry in LocalVariableTable for outer class object in an inner class constructor(Java Bytecode)

Step1: I compiled the following code:

public class OuterClass {
class InnerClass{

    }
}  

I've got OuterClass.class and OterClass$InnerClass.class

Step2: I use javap to check the bytecode of the inner class. It is very strange that the constructor method uses " 1: aload_1", but in the LocalVariableTable, there is only one entry for "this" that is accessible by aload_0. I assume that aload_1 is to load the passing-in parameter--which is the reference of the outer class object--to the top of the stack.

My Question: Why doesn't the compiler create an entry for it(the reference of the outer class that is passed to the constructor)?

I tried with Jsdk 1.4 and 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;


}

The LocalVariableTable is purely for debugging purposes - it has no effect on execution. Therefore, it only includes the source visible variables, since that's what the debugger is interested in. There's no reason to include compiler generated variables.

I think it's just because it doesn't need an entry in the local variable table, being an argument that never needs to get referenced in any other way than as an argument.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM