A simple example:
public class Test { public static void main(String[] args) throws Exception { List<String> list = new ArrayList<String>() { { add("a"); add("b"); } }; } }
We then compiled after the class file out to look, what happened. First of all see is a Test.java compiled a 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
Then we look at what Test.class itself is compiled into the direct use jdk javap comes on the line.
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 }
Then look at what the other Test $ 1.class, from the anti-compiled code below will know this Test $ 1 is a subclass of ArrayList. Combined with the original java code, I know this is actually written to create an anonymous subclass of ArrayList of it. Inside the braces is equivalent to that layer you add to the class initialization of a code block, this block of code will be automatically incorporated into the class init method, which is the object's constructor.
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 }