匿名子类

 一个简单的例子:

public class Test {

    public static void main(String[] args) throws Exception {
        List<String> list = new ArrayList<String>() {
            {
                add("a");
                add("b");
            }
        };
    }
}

然后我们把编译过后的class文件拿出来看看,究竟发生了什么。首先看到的是,一个Test.java编译出了2个class

isaac-mbp:basic foxty$ ls -l
total 16
-rw-r--r--  1 foxty  staff  542  2  9 22:08 Test$1.class
-rw-r--r--  1 foxty  staff  629  2  9 22:08 Test.class

接着我们看看本身的Test.class被编译成了什么,直接用jdk自带的javap就行。

isaac-mbp:basic foxty$ javap -c Test.class 
Compiled from "Test.java"
public class com.foxty.basic.Test {
  public com.foxty.basic.Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]) throws java.lang.Exception;
    Code:
       0: new           #2                  // class com/foxty/basic/Test$1-这里创建了一个Test$1的类
       3: dup
       4: invokespecial #3                  // Method com/foxty/basic/Test$1."<init>":()V
       7: astore_1
       8: return
}

接着再来看看另外一个Test$1.class是什么,从下面反编译出来的代码就知道这个Test$1就是一个ArrayList的子类。结合原来的java代码,就知道这个写法其实就是创建了一个ArrayList的匿名子类而已。里面的那层大括号就相当于你给类加了一个初始化的代码块,这个代码块会自动合并到类的init方法,也就是对象的构造方法里。

isaac-mbp:basic foxty$ javap -c Test\$1.class 
Compiled from "Test.java"
final class com.foxty.basic.Test$1 extends java.util.ArrayList<java.lang.String> {
  com.foxty.basic.Test$1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/util/ArrayList."<init>":()V
       4: aload_0
       5: ldc           #2                  // String a
       7: invokevirtual #3                  // Method add:(Ljava/lang/Object;)Z
      10: pop
      11: aload_0
      12: ldc           #4                  // String b
      14: invokevirtual #3                  // Method add:(Ljava/lang/Object;)Z
      17: pop
      18: return
}

猜你喜欢

转载自www.cnblogs.com/aaronRhythm/p/11014421.html