什么是双大括号初始化语法({{…}})在Java?


当前回答

你是说像这样的事?

List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};

这是在创建时初始化数组列表(hack)

其他回答

我认为有必要强调的是,在Java中没有“双大括号初始化”这样的东西。甲骨文网站没有这个术语。在这个例子中,有两个特性一起使用:匿名类和初始化程序块。开发人员似乎已经忘记了旧的初始化程序块,并在这个主题中引起了一些混乱。引用自Oracle文档:

实例变量的初始化块看起来就像静态初始化块,但是没有static关键字:

{
    // whatever code is needed for initialization goes here
}

在其他用途中,它是初始化集合的快捷方式。了解更多…

双大括号初始化创建一个从指定类派生的匿名类(外大括号),并在该类中提供一个初始化程序块(内大括号)。如。

new ArrayList<Integer>() {{
   add(1);
   add(2);
}};

注意,使用这种双大括号初始化的效果是创建匿名的内部类。创建的类有一个隐式this指针指向周围的外部类。虽然通常不是问题,但在某些情况下,例如序列化或垃圾收集时,它可能会导致痛苦,值得注意这一点。

正如lukas Eder指出的那样,必须避免对集合进行双括号初始化。

它创建了一个匿名的内部类,并且由于所有内部类都保留了对父实例的引用,所以如果这些集合对象被其他对象引用,而不仅仅是声明的对象引用,那么它可以(99%可能会)防止垃圾收集。

Java 9引入了方便的方法List。的集合。的,和地图。的,应该用它代替。它们比双括号初始化式更快更有效。

第一个大括号创建了一个新的匿名类,第二组大括号创建了一个实例初始化器,类似于静态块。

正如其他人指出的那样,使用它并不安全。

但是,您总是可以使用这个替代方法来初始化集合。

Java 8

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));

Java 9

List<String> list = List.of("A", "B", "C");