Attr的visitNewClass()方法解读

Posted extjs4

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Attr的visitNewClass()方法解读相关的知识,希望对你有一定的参考价值。

 

 

class E{
	class C<T1>{
		// C的构造函数
		public <T2> C(){ }
		
		public void t(){
			E e = new E();
			e.new <String>C<Integer>(){};
		}
	}
}

 

通过调用visitNewClass()方法后,e.new <String>C<Integer>(){}方法被改写为:

new <String>C<Integer>(e<*nullchk*>){
    <T2 extends java.lang.Object>(com.test19.E x0) {
           x0.<T2>super();
     }
}

  

 

编译后生成3个Class文件,如下:

(1)E.class,通过调用Attr类的visitNewClass()方法后,e.new <String>C<Integer>(){}方法被改写为: 

class E {
    
    E() {
        super();
    }
    
    class C<T1> {
        
        public <T2>C() {
            super();
        }
        
        public void t() {
            E e = new E();
            new <String>C<Integer>(e<*nullchk*>){                
                <T2 extends .java.lang.Object>(.com.test19.E x0) {
                    x0.<T2>super();
                }
            };
        }
    }
}

最终的字节码如下:

class com.test19.E
  SourceFile: "Test07.java"
  InnerClasses:
       #5= #4 of #2; //C=class com/test19/E$C of class com/test19/E
  minor version: 0
  major version: 51
  flags: ACC_SUPER
Constant pool:
   #1 = Methodref          #3.#16         //  java/lang/Object."<init>":()V
   #2 = Class              #17            //  com/test19/E
   #3 = Class              #18            //  java/lang/Object
   #4 = Class              #19            //  com/test19/E$C
   #5 = Utf8               C
   #6 = Utf8               InnerClasses
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/test19/E;
  #14 = Utf8               SourceFile
  #15 = Utf8               Test07.java
  #16 = NameAndType        #7:#8          //  "<init>":()V
  #17 = Utf8               com/test19/E
  #18 = Utf8               java/lang/Object
  #19 = Utf8               com/test19/E$C
{
  com.test19.E();
    flags:
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 4: 0
        line 5: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   Lcom/test19/E;
}

  

 

  

 

(2)E$C通过调用desugar类后如下:  

class E$C {
    /*synthetic*/ final E this$0;
    
    public E$C(/*synthetic*/ final E this$0) {
        this.this$0 = this$0;
        super();
    }
    
    public void t() {
        E e = new E();
        new <String>E$C$1(this, e<*nullchk*>);
    }
}

最终的字节码如下:

class com.test19.E$C<T1 extends java.lang.Object> extends java.lang.Object
  Signature: #29                          // <T1:Ljava/lang/Object;>Ljava/lang/Object;
  SourceFile: "Test07.java"
  InnerClasses:
       #10= #8 of #3; //C=class com/test19/E$C of class com/test19/E
       #5; //class com/test19/E$C$1
  minor version: 0
  major version: 51
  flags: ACC_SUPER
Constant pool:
   #1 = Fieldref           #8.#32         //  com/test19/E$C.this$0:Lcom/test19/E;
   #2 = Methodref          #9.#33         //  java/lang/Object."<init>":()V
   #3 = Class              #34            //  com/test19/E
   #4 = Methodref          #3.#33         //  com/test19/E."<init>":()V
   #5 = Class              #35            //  com/test19/E$C$1
   #6 = Methodref          #9.#36         //  java/lang/Object.getClass:()Ljava/lang/Class;
   #7 = Methodref          #5.#37         //  com/test19/E$C$1."<init>":(Lcom/test19/E$C;Lcom/test19/E;)V
   #8 = Class              #38            //  com/test19/E$C
   #9 = Class              #39            //  java/lang/Object
  #10 = Utf8               C
  #11 = Utf8               InnerClasses
  #12 = Utf8
  #13 = Utf8               this$0
  #14 = Utf8               Lcom/test19/E;
  #15 = Utf8               <init>
  #16 = Utf8               (Lcom/test19/E;)V
  #17 = Utf8               Code
  #18 = Utf8               LineNumberTable
  #19 = Utf8               LocalVariableTable
  #20 = Utf8               this
  #21 = Utf8               Lcom/test19/E$C;
  #22 = Utf8               LocalVariableTypeTable
  #23 = Utf8               Lcom/test19/E$C<TT1;>;
  #24 = Utf8               Signature
  #25 = Utf8               <T2:Ljava/lang/Object;>()V
  #26 = Utf8               t
  #27 = Utf8               ()V
  #28 = Utf8               e
  #29 = Utf8               <T1:Ljava/lang/Object;>Ljava/lang/Object;
  #30 = Utf8               SourceFile
  #31 = Utf8               Test07.java
  #32 = NameAndType        #13:#14        //  this$0:Lcom/test19/E;
  #33 = NameAndType        #15:#27        //  "<init>":()V
  #34 = Utf8               com/test19/E
  #35 = Utf8               com/test19/E$C$1
  #36 = NameAndType        #40:#41        //  getClass:()Ljava/lang/Class;
  #37 = NameAndType        #15:#42        //  "<init>":(Lcom/test19/E$C;Lcom/test19/E;)V
  #38 = Utf8               com/test19/E$C
  #39 = Utf8               java/lang/Object
  #40 = Utf8               getClass
  #41 = Utf8               ()Ljava/lang/Class;
  #42 = Utf8               (Lcom/test19/E$C;Lcom/test19/E;)V
{
  final com.test19.E this$0;
    flags: ACC_FINAL, ACC_SYNTHETIC

  public <T2 extends java/lang/Object> com.test19.E$C();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #1                  // Field this$0:Lcom/test19/E;
         5: aload_0
         6: invokespecial #2                  // Method java/lang/Object."<init>":()V
         9: return
      LineNumberTable:
        line 7: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      10     0  this   Lcom/test19/E$C;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0      10     0  this   Lcom/test19/E$C<TT1;>;
    Signature: #25                          // <T2:Ljava/lang/Object;>()V

  public void t();
    flags: ACC_PUBLIC
    Code:
      stack=5, locals=2, args_size=1
         0: new           #3                  // class com/test19/E
         3: dup
         4: invokespecial #4                  // Method com/test19/E."<init>":()V
         7: astore_1
         8: new           #5                  // class com/test19/E$C$1
        11: dup
        12: aload_0
        13: aload_1
        14: dup
        15: invokevirtual #6                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
        18: pop
        19: invokespecial #7                  // Method com/test19/E$C$1."<init>":(Lcom/test19/E$C;Lcom/test19/E;)V
        22: pop
        23: return
      LineNumberTable:
        line 10: 0
        line 11: 8
        line 12: 23
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      24     0  this   Lcom/test19/E$C;
               8      16     1     e   Lcom/test19/E;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0      24     0  this   Lcom/test19/E$C<TT1;>;
}

  

  

 

(3)E$C$1通过调用desugar类后代码如下: 

class E$C$1 extends com.test19.E$C {
    /*synthetic*/ final E$C this$1;
    
    E$C$1(/*synthetic*/ final E$C this$1, com.test19.E x0) {
        this.this$1 = this$1;
        <T2>super(x0<*nullchk*>);
    }
}

 

最终编译后的字节码如下:

class com.test19.E$C$1 extends com.test19.E$C<java.lang.Integer>
  Signature: #23                          // Lcom/test19/E$C<Ljava/lang/Integer;>;
  SourceFile: "Test07.java"
  EnclosingMethod: #5.#27                 // com.test19.E$C.t
  InnerClasses:
       #7= #5 of #33; //C=class com/test19/E$C of class com/test19/E
       #4; //class com/test19/E$C$1
  minor version: 0
  major version: 51
  flags: ACC_SUPER
Constant pool:
   #1 = Fieldref           #4.#28         //  com/test19/E$C$1.this$1:Lcom/test19/E$C;
   #2 = Methodref          #29.#30        //  java/lang/Object.getClass:()Ljava/lang/Class;
   #3 = Methodref          #5.#31         //  com/test19/E$C."<init>":(Lcom/test19/E;)V
   #4 = Class              #32            //  com/test19/E$C$1
   #5 = Class              #34            //  com/test19/E$C
   #6 = Utf8               this$1
   #7 = Utf8               C
   #8 = Utf8               InnerClasses
   #9 = Utf8               Lcom/test19/E$C;
  #10 = Utf8               <init>
  #11 = Utf8               (Lcom/test19/E$C;Lcom/test19/E;)V
  #12 = Utf8               Code
  #13 = Utf8               LineNumberTable
  #14 = Utf8               LocalVariableTable
  #15 = Utf8               this
  #16 = Utf8
  #17 = Utf8               Lcom/test19/E$C$1;
  #18 = Utf8               x0
  #19 = Utf8               Lcom/test19/E;
  #20 = Utf8               LocalVariableTypeTable
  #21 = Utf8               Lcom/test19/E$C.1;
  #22 = Utf8               Signature
  #23 = Utf8               Lcom/test19/E$C<Ljava/lang/Integer;>;
  #24 = Utf8               SourceFile
  #25 = Utf8               Test07.java
  #26 = Utf8               EnclosingMethod
  #27 = NameAndType        #35:#36        //  t:()V
  #28 = NameAndType        #6:#9          //  this$1:Lcom/test19/E$C;
  #29 = Class              #37            //  java/lang/Object
  #30 = NameAndType        #38:#39        //  getClass:()Ljava/lang/Class;
  #31 = NameAndType        #10:#40        //  "<init>":(Lcom/test19/E;)V
  #32 = Utf8               com/test19/E$C$1
  #33 = Class              #41            //  com/test19/E
  #34 = Utf8               com/test19/E$C
  #35 = Utf8               t
  #36 = Utf8               ()V
  #37 = Utf8               java/lang/Object
  #38 = Utf8               getClass
  #39 = Utf8               ()Ljava/lang/Class;
  #40 = Utf8               (Lcom/test19/E;)V
  #41 = Utf8               com/test19/E
{
  final com.test19.E$C this$1;
    flags: ACC_FINAL, ACC_SYNTHETIC

  com.test19.E$C$1(com.test19.E$C, com.test19.E);
    flags:
    Code:
      stack=3, locals=3, args_size=3
         0: aload_0
         1: aload_1
         2: putfield      #1                  // Field this$1:Lcom/test19/E$C;
         5: aload_0
         6: aload_2
         7: dup
         8: invokevirtual #2                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
        11: pop
        12: invokespecial #3                  // Method com/test19/E$C."<init>":(Lcom/test19/E;)V
        15: return
      LineNumberTable:
        line 11: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      16     0  this   Lcom/test19/E$C$1;
               0      16     2    x0   Lcom/test19/E;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0      16     0  this   Lcom/test19/E$C.1;
}

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

以上是关于Attr的visitNewClass()方法解读的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed解读(示例代

JVM源码分析之堆外内存完全解读

Javac中的nullcheck

解读隐藏代码

PostgreSQL 源码解读(24)- 查询语句#9(查询重写)

thinkphp 里sql 语句如何解读????