什么是双大括号初始化语法({{…}})在Java?
当前回答
为了避免双大括号初始化的所有负面影响,例如:
打破了“平等”的兼容性。 使用直接赋值时不执行检查。 可能存在内存泄漏。
做下面的事情:
创建单独的“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
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Java 9
List<String> list = List.of("A", "B", "C");
我认为有必要强调的是,在Java中没有“双大括号初始化”这样的东西。甲骨文网站没有这个术语。在这个例子中,有两个特性一起使用:匿名类和初始化程序块。开发人员似乎已经忘记了旧的初始化程序块,并在这个主题中引起了一些混乱。引用自Oracle文档:
实例变量的初始化块看起来就像静态初始化块,但是没有static关键字:
{
// whatever code is needed for initialization goes here
}
双大括号初始化创建一个从指定类派生的匿名类(外大括号),并在该类中提供一个初始化程序块(内大括号)。如。
new ArrayList<Integer>() {{
add(1);
add(2);
}};
注意,使用这种双大括号初始化的效果是创建匿名的内部类。创建的类有一个隐式this指针指向周围的外部类。虽然通常不是问题,但在某些情况下,例如序列化或垃圾收集时,它可能会导致痛苦,值得注意这一点。
1-没有双括号这样的东西: 我想指出,没有双大括号初始化这样的东西。传统的初始化块只有一个大括号。第二个花括号块与初始化无关。答案说这两个大括号初始化了一些东西,但它不是这样的。
2-不只是匿名类,而是所有类: 几乎所有的答案都说它是在创建匿名内部类时使用的。我认为阅读这些答案的人会得到这样的印象,即这只在创建匿名内部类时使用。但它在所有课程中都被使用。读这些答案,它看起来像是一些全新的专门用于匿名类的特殊功能,我认为这是误导。
3- The purpose is just about placing brackets after each other, not new concept: Going further, this question talks about situation when second opening bracket is just after first opening bracket. When used in normal class usually there is some code between two braces, but it is totally the same thing. So it is a matter of placing brackets. So I think we should not say that this is some new exciting thing, because this is the thing which we all know, but just written with some code between brackets. We should not create new concept called "double brace initialization".
创建嵌套的匿名类与两个大括号无关: 我不同意创建太多匿名类的说法。你创建它们不是因为一个初始化块,而是因为你创建了它们。即使你没有使用两个大括号初始化,它们也会被创建,所以即使没有初始化,这些问题也会发生……初始化不是创建初始化对象的因素。
此外,我们不应该谈论使用这个不存在的东西“双括号初始化”,甚至是普通的单括号初始化所产生的问题,因为所描述的问题只是因为创建匿名类而存在,所以它与原始问题无关。但是所有的答案都给读者留下了这样的印象:创建匿名类并不是错误,而是这个邪恶的(不存在的)叫做“双括号初始化”的东西。
推荐文章
- codestyle;把javadoc放在注释之前还是之后?
- 如何在Spring中定义List bean ?
- 将Set<T>转换为List<T>的最简洁的方法
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作
- Java Regex捕获组
- Openssl不被视为内部或外部命令
- 如何添加自定义方法到Spring Data JPA
- 如何在Ubuntu中设置Java环境路径
- 无法执行dex:在Eclipse中超过GC开销限制
- 有人能解释一下JPA和Hibernate中的mappedBy吗?