在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. JavaWeb多文件上传及zip打包下载

    项目中经常会使用到文件上传及下载的功能.本篇文章总结场景在JavaWeb环境下,多文件上传及批量打包下载功能,包括前台及后台部分.  首先明确一点:  无法通过页面的无刷新ajax请求,直接发下载.上 ...

  2. js五道经典练习题--第二道仿qq聊天框

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  3. UNIGUI接收普通消息和被动回复用户消息

    接收普通消息和被动回复用户消息 用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复 ...

  4. Android-Kotlin-代理和委托

    代理和委托,在生活中的案例有很多: 例如:小明工作很忙,需要办理银行卡,此时他委托给>>小李去给自己办理银行卡,小李来到办理中心 把自己的身份证/小李的身份证,给办理人员,说是小明委托我, ...

  5. 第21件事 资源支持离不开RACI表

    十步法的第九步寻求资源支持.资源主要包括人力资源.物力资源和财力资源.人力资源,即需要多少人:物力资源,即需要多少软硬件设备:财力资源,即需要多少预算.根据产品或项目目标,资源估算时要考虑需要什么样的 ...

  6. 撸.NET Core的正确姿势

    特点 案例基于刚发布的.NET Core 2.1 只需一台Linux服务器搞定一切, 全程无需自己配置dotnet环境, 需要熟悉git docker基础知识可有可无, 过了下面几个步骤,你就已经入门 ...

  7. StriveEngine-UDP

    文章中的StriveEngine.dll版本为V3.9.0.0,源码下载请到 这里 UDP比TCP通信,就相对简单多了 先上代码,建立2个控制台程序,分别为SEUDP1,SEUDP2,其中SEUDP1 ...

  8. WPF学习笔记(4):获取DataGridTemplateColumn模板定义的内容控件

    在之前的DataGrid的DataGridTemplateColumn列中,自定义了一个TextBox控件,但是在C#代码中提示找不到这个控件,导致无法对该控件进行操作.在网上搜索后,发现一些处理方法 ...

  9. ASP.NET MVC的切片(Section)脚本(script)

    在ASP.NET MVC使用切片脚本,实在是很溜. 在使用layout之后,只是视图套用_Layout之后,在视图中任一位置任一时候均可以使用切片脚本. 首先在_Layout.cshtml定一些规则: ...

  10. libffi-dev : 依赖: libffi6 (= 3.2.1-4) 但是 3.2.1-4kord 正要被安装

    原文链接:https://blog.csdn.net/u013992330/article/details/85135629 中标麒麟安装python库:sshtunnel 的时候提示缺少ffi.h文 ...