在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. 基础运动move.js

    /* * 事件绑定 */ function myAddEvent(obj,ev,fn){ if(obj.attachEvent){ obj.attachEvent('on' + ev,fn); }el ...

  2. 【慕课网实战】Spark Streaming实时流处理项目实战笔记三之铭文升级版

    铭文一级: Flume概述Flume is a distributed, reliable, and available service for efficiently collecting(收集), ...

  3. 阿里云oss怎么上传文件夹

    最近公司在做工程项目,实现文件夹云存储上传 网上找了很久,发现很多项目都存在一些问题,但还是让我找到了一个成熟的项目. 工程: 对项目的文件夹云存储上传功能做出分析,找出文件夹上传的原理,对文件夹的云 ...

  4. Webpack 学习2

    webpack + react 优化:缩小js包体积 webpack 介绍 & 安装 & 常用命令 30分钟手把手教你学webpack实战 Webpack 中文指南

  5. 第85讲:Scala中For表达式的强大表现力实战

    今天来学一下scala中的For表达式的用法. package scala.learn case class Persons(name:String,isMale:Boolean,children:P ...

  6. HashMap原理、源码、实践

    HashMap是一种十分常用的数据结构,作为一个应用开发人员,对其原理.实现的加深理解有助于更高效地进行数据存取.本文所用的jdk版本为1.5. 使用HashMap <Effective JAV ...

  7. codeforces 877e

    E. Danil and a Part-time Job time limit per test 2 seconds memory limit per test 256 megabytes input ...

  8. hdu 4861

    http://acm.hdu.edu.cn/showproblem.php?pid=4861 两个人进行游戏,桌上有k个球,第i个球的值为1^i+2^i+⋯+(p−1)^i%p,两个人轮流取,如果Do ...

  9. hdu 5047 大数找规律

    http://acm.hdu.edu.cn/showproblem.php?pid=5047 找规律 信kuangbin,能AC #include <stdio.h> #include & ...

  10. javascript 编码规范

    前端编码风格规范(3)-- JavaScript 规范 其他三个写的也挺好的,不过html和css我已经参照了其他的. 防污染与IIFE (function($, w, d){ 'use strict ...