在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()方法解读的更多相关文章

  1. jQuery操纵DOM元素属性 attr()和removeAtrr()方法使用详解

    jQuery操纵DOM元素属性 attr()和removeAtrr()方法使用详解 jQuery中操纵元素属性的方法: attr(): 读或者写匹配元素的属性值. removeAttr(): 从匹配的 ...

  2. jquery中dom元素的attr和prop方法的理解

    一.背景 在编写使用高版本[ jQuery 1.6 开始新增了一个方法 prop()]的jquery插件进行编写js代码的时候,经常不知道dom元素的attr和prop方法到底有什么区别?各自有什么应 ...

  3. input是否checked与使用jquery的attr或prop方法无关

    最近在项目中有这样一个需求,用户在下单时可以选择优惠券,也可取消选择,并且可以多次选择,取消. 这是一个典型的input标签checked功能,博主使用radio元素实现此需求,但是优惠券只能选中,不 ...

  4. Connection 对象简介 方法解读 JDBC简介(四)

    通过驱动管理器DriverManager的getConnection方法,可以创建到指定URL的连接     Connection conn = DriverManager.getConnection ...

  5. jQuery .attr()和.removeAttr()方法操作元素属性示例

    今天主要和大家一起分享一下如何使用jQuery的.attr()和.removeAttr()方法读取,添加,修改,删除元素的属性.大家在平时的Web页面制作中都有碰到如何动态的获取元素的属性和属性值,或 ...

  6. jQuery中attr和prop方法的区别

    jQuery中attr和prop方法的区别。 http://my.oschina.net/bosscheng/blog/125833 http://www.javascript100.com/?p=8 ...

  7. $().attr()的使用方法 &amp;&amp; $().html()与$().text()的差别

    <1>$().attr()的使用方法 </pre><pre class="html" name="code"><htm ...

  8. Java安全之原生readObject方法解读

    Java安全之原生readObject方法解读 0x00 前言 在上篇文章分析shiro中,遇到了Shiro重写了ObjectInputStream的resolveClass导致的一些基于Invoke ...

  9. jQuery 中 attr() 和 prop() 方法的区别

    前几天,有人给 Multiple Select 插件 提了问题: setSelects doesn't work in Firefox when using jquery 1.9.0 一直都在用 jQ ...

随机推荐

  1. chrome 字体太浅,如何设置

    "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-directwrite-for-ui

  2. (CodeForces 548B 暴力) Mike and Fun

    http://codeforces.com/problemset/problem/548/B Mike and some bears are playing a game just for fun. ...

  3. java静态代码块、普通代码

    参考文章:http://www.cnblogs.com/qinpengming/p/5227227.html Java中经常有一些静态块,这是用来在生成类之前进行的初始化,无论java还C++语言中的 ...

  4. Scala_基本语法

    基本语法 声明值和变量 Scala有两种类型的变量: val:是不可变的(变量的引用不可变),在声明时就必须被初始化,而且初始化以后就不能再赋值: var:声明的时候需要进行初始化,初始化以还可以再对 ...

  5. [ 9.12 ]CF每日一题系列—— 960B暴力数组

    Description: 给你两个数组,顺序一定,问你第一个数组连续的几个值等于下一个数组连续的几个值,然后寻找这个值得最大值,也就是满足就换 Solution: 用两个变量索引,判断即可 #incl ...

  6. HDU2844买表——多重背包初探

    HDU2844买表多重背包问题题目大意都不大好懂,是利用手头上的硬币看看能组合出多少种价格,也就是跑完背包,看看有多少背包符合要求 剩下的就是多重背包的问题了1.第一个处理办法就是直接当01背包进行存 ...

  7. python函数知识

    一.三目运算 也叫三元运算,例如result=x if x<y else y 二.集合(set) 返回主页集合(set):把不同的元素组成一起形成集合,是python基本的数据类型.集合元素(s ...

  8. iOS笔记之UIKit_UIButton

    //UIButton的基本属性 _btn = [UIButton buttonWithType:UIButtonTypeCustom]; _btn.frame = CGRectMake(0, 200, ...

  9. C#读取excel文件提示未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序

    错误描述: 在VS2010执行读取excel文件时,报错"未在本地计算机上注册"Microsoft.ACE.OLEDB.12.0"提供程序" 业务代码: //下 ...

  10. Weekly Contest 133

    1030. Matrix Cells in Distance Order We are given a matrix with R rows and C columns has cells with ...