Attr的visitNewClass()方法解读
在visitNewClass()方法中有如下注释:
We are seeing an anonymous class instance creation.
In this case, the class instance creation expression
E.new <typeargs1>C<typargs2>(args) { ... }
is represented internally as
E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } ) .
This expression is then *transformed* as follows:
(1) add a STATIC flag to the class definition if the current environment is static
(2) add an extends or implements clause
(3) add a constructor.
For instance, if C is a class, and ET is the type of E, the expression
E.new <typeargs1>C<typargs2>(args) { ... }
is translated to (where X is a fresh name and typarams is the
parameter list of the super constructor):
new <typeargs1>X(<*nullchk*>E, args)
where
X extends C<typargs2> { <typarams> X(ET e, args) { e.<typeargs1>super(args) } ... }
举个例子,如下:
class E{ class C<T1>{ // C的构造函数 public <T2> C(){ } public void t(){ E e = new E(); e.new <String>C<Integer>(){}; } } }
按如上的描述,应该被改写为:
class E{ class C<T1>{ // C的构造函数 public <T2> C(){ } public void t(){ E e = new E(); new <String>X(e); // 更改为了这样的形式 } } } class X extends E.C<Integer>{ <T2> X(E e){ e.<T2>super(); } }
传入visitNewClass()方法的tree参数如下截图。
通过调用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()方法解读的更多相关文章
- jQuery操纵DOM元素属性 attr()和removeAtrr()方法使用详解
jQuery操纵DOM元素属性 attr()和removeAtrr()方法使用详解 jQuery中操纵元素属性的方法: attr(): 读或者写匹配元素的属性值. removeAttr(): 从匹配的 ...
- jquery中dom元素的attr和prop方法的理解
一.背景 在编写使用高版本[ jQuery 1.6 开始新增了一个方法 prop()]的jquery插件进行编写js代码的时候,经常不知道dom元素的attr和prop方法到底有什么区别?各自有什么应 ...
- input是否checked与使用jquery的attr或prop方法无关
最近在项目中有这样一个需求,用户在下单时可以选择优惠券,也可取消选择,并且可以多次选择,取消. 这是一个典型的input标签checked功能,博主使用radio元素实现此需求,但是优惠券只能选中,不 ...
- Connection 对象简介 方法解读 JDBC简介(四)
通过驱动管理器DriverManager的getConnection方法,可以创建到指定URL的连接 Connection conn = DriverManager.getConnection ...
- jQuery .attr()和.removeAttr()方法操作元素属性示例
今天主要和大家一起分享一下如何使用jQuery的.attr()和.removeAttr()方法读取,添加,修改,删除元素的属性.大家在平时的Web页面制作中都有碰到如何动态的获取元素的属性和属性值,或 ...
- jQuery中attr和prop方法的区别
jQuery中attr和prop方法的区别。 http://my.oschina.net/bosscheng/blog/125833 http://www.javascript100.com/?p=8 ...
- $().attr()的使用方法 && $().html()与$().text()的差别
<1>$().attr()的使用方法 </pre><pre class="html" name="code"><htm ...
- Java安全之原生readObject方法解读
Java安全之原生readObject方法解读 0x00 前言 在上篇文章分析shiro中,遇到了Shiro重写了ObjectInputStream的resolveClass导致的一些基于Invoke ...
- jQuery 中 attr() 和 prop() 方法的区别
前几天,有人给 Multiple Select 插件 提了问题: setSelects doesn't work in Firefox when using jquery 1.9.0 一直都在用 jQ ...
随机推荐
- chrome 字体太浅,如何设置
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-directwrite-for-ui
- (CodeForces 548B 暴力) Mike and Fun
http://codeforces.com/problemset/problem/548/B Mike and some bears are playing a game just for fun. ...
- java静态代码块、普通代码
参考文章:http://www.cnblogs.com/qinpengming/p/5227227.html Java中经常有一些静态块,这是用来在生成类之前进行的初始化,无论java还C++语言中的 ...
- Scala_基本语法
基本语法 声明值和变量 Scala有两种类型的变量: val:是不可变的(变量的引用不可变),在声明时就必须被初始化,而且初始化以后就不能再赋值: var:声明的时候需要进行初始化,初始化以还可以再对 ...
- [ 9.12 ]CF每日一题系列—— 960B暴力数组
Description: 给你两个数组,顺序一定,问你第一个数组连续的几个值等于下一个数组连续的几个值,然后寻找这个值得最大值,也就是满足就换 Solution: 用两个变量索引,判断即可 #incl ...
- HDU2844买表——多重背包初探
HDU2844买表多重背包问题题目大意都不大好懂,是利用手头上的硬币看看能组合出多少种价格,也就是跑完背包,看看有多少背包符合要求 剩下的就是多重背包的问题了1.第一个处理办法就是直接当01背包进行存 ...
- python函数知识
一.三目运算 也叫三元运算,例如result=x if x<y else y 二.集合(set) 返回主页集合(set):把不同的元素组成一起形成集合,是python基本的数据类型.集合元素(s ...
- iOS笔记之UIKit_UIButton
//UIButton的基本属性 _btn = [UIButton buttonWithType:UIButtonTypeCustom]; _btn.frame = CGRectMake(0, 200, ...
- C#读取excel文件提示未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序
错误描述: 在VS2010执行读取excel文件时,报错"未在本地计算机上注册"Microsoft.ACE.OLEDB.12.0"提供程序" 业务代码: //下 ...
- Weekly Contest 133
1030. Matrix Cells in Distance Order We are given a matrix with R rows and C columns has cells with ...