什么是双大括号初始化语法({{…}})在Java?
当前回答
双大括号初始化创建一个从指定类派生的匿名类(外大括号),并在该类中提供一个初始化程序块(内大括号)。如。
new ArrayList<Integer>() {{
add(1);
add(2);
}};
注意,使用这种双大括号初始化的效果是创建匿名的内部类。创建的类有一个隐式this指针指向周围的外部类。虽然通常不是问题,但在某些情况下,例如序列化或垃圾收集时,它可能会导致痛苦,值得注意这一点。
其他回答
在其他用途中,它是初始化集合的快捷方式。了解更多…
双大括号初始化创建一个从指定类派生的匿名类(外大括号),并在该类中提供一个初始化程序块(内大括号)。如。
new ArrayList<Integer>() {{
add(1);
add(2);
}};
注意,使用这种双大括号初始化的效果是创建匿名的内部类。创建的类有一个隐式this指针指向周围的外部类。虽然通常不是问题,但在某些情况下,例如序列化或垃圾收集时,它可能会导致痛苦,值得注意这一点。
正如lukas Eder指出的那样,必须避免对集合进行双括号初始化。
它创建了一个匿名的内部类,并且由于所有内部类都保留了对父实例的引用,所以如果这些集合对象被其他对象引用,而不仅仅是声明的对象引用,那么它可以(99%可能会)防止垃圾收集。
Java 9引入了方便的方法List。的集合。的,和地图。的,应该用它代替。它们比双括号初始化式更快更有效。
为了避免双大括号初始化的所有负面影响,例如:
打破了“平等”的兼容性。 使用直接赋值时不执行检查。 可能存在内存泄漏。
做下面的事情:
创建单独的“Builder”类,专门用于双大括号初始化。 用默认值声明字段。 将对象创建方法放在该类中。
例子:
public class MyClass {
public static class Builder {
public int first = -1 ;
public double second = Double.NaN;
public String third = null ;
public MyClass create() {
return new MyClass(first, second, third);
}
}
protected final int first ;
protected final double second;
protected final String third ;
protected MyClass(
int first ,
double second,
String third
) {
this.first = first ;
this.second= second;
this.third = third ;
}
public int first () { return first ; }
public double second() { return second; }
public String third () { return third ; }
}
用法:
MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();
优点:
简单易用。 不要破坏“对等”的兼容性。 您可以在创建方法中执行检查。 无内存泄漏。
缺点:
一个也没有。
因此,我们有了有史以来最简单的java构建器模式。
查看github: java-sf-builder-simple-example中的所有示例
关于双大括号初始化的有趣应用,请参阅这里的Dwemthy 's Array in Java。
摘录
private static class IndustrialRaverMonkey
extends Creature.Base {{
life = 46;
strength = 35;
charisma = 91;
weapon = 2;
}}
private static class DwarvenAngel
extends Creature.Base {{
life = 540;
strength = 6;
charisma = 144;
weapon = 50;
}}
现在,准备好迎接香肠味和培根味的大战吧!
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap