Java中双大括号写法的作用
如何给集合快速初始化呢?可能会用到下面这种写法。
public class Main1 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>() {
{
add("hello");
add("world");
}
};
System.out.println(list);
}
}
一个大括号
一个大括号还是比较好理解的
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
匿名内部类的一种写法,并不是真正实例化Runnable这个接口。等同于
public class Main1 {
class TestThread implements Runnable{
@Override
public void run() {
}
}
public static void main(String[] args) {
TestThread testThread = new TestThread();
new Thread(testThread).start();
}
}
两个大括号
编译一下下面的代码
public class Main1 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>() {
{
add("hello");
add("world");
}
};
System.out.println(list);
}
}
得到了两个字节码文件
反编译
很明显可以看到,java编译器是如何处理双大括号语法的:
隐式创建了一个类,继承ArrayList,并在这个类的构造方法中,执行双大括号中的代码。
问题
这种写法会带来一种问题,比如我想要初始化多个List
public class Main1 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>() {
{
add("hello");
add("world");
}
};
System.out.println(list);
List<String> list2 = new ArrayList<String>() {
{
add("hello");
add("world");
}
};
}
}
每使用一次这个语法,就会多一个字节码文件,更深层次的问题暂时没遇到,不过最好还是少用吧。
最后跑个题,传统内部类编译后得到如下结果。
public class Main2 {
class innerClass{
String year;
public void hello() {
say1();
}
}
void say1() {
System.out.println("1");
}
public static void main(String[] args) {
Main2 main2 = new Main2();
}
}
可见内部类能访问外部类的方法,是因为把外部类的this通过构造函数传了进来。
参考:
