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解读(示例代