我个人非常喜欢实例初始化器 - 我使用它们来为诸如集合之类的东西分配默认值,因此在编写构造函数时,我不必记住每次都为它们分配相同的默认值。对我来说这似乎很优雅 - 避免恼人的NPE弹出并避免重复代码。私有方法似乎不太好,因为a)它不能为最终字段赋值,b)它可以在代码中的其他地方运行,c)在每个构造函数的开头仍然需要显式调用该方法。 / p>
然而,与我所说过的其他人的另一面是,他们感到困惑,有些人阅读代码可能无法理解他们做什么或何时被调用,因此他们可能会导致比他们解决的问题更多的问题。 / p>
是否应该鼓励或避免使用这些初始化程序?或者它是“每个人都有自己的”案例?
答案 0 :(得分:3)
具体取决于您的代码中Java读者的知识水平,以及替代方案是否切实可行。
替代方案是:
由于初始化程序并不常见,因此只有在使用它们有明显优势时才应该使用它们。我最近使用的是:
private final Collator collator = Collator.getInstance();
{
collator.setStrength(Collator.SECONDARY);
}
在一个具有几个构造函数的类中,这些构造函数具有相当不同的参数列表和六个其他字段。
答案 1 :(得分:1)
我并没有真正使用它们,但是我可以看到它们有用的一种情况是当你有多个构造函数,而不是自己调用(this(..))时,需要共享一些常见的初始化逻辑,而不需要创建一个特定的私人方法。 哦,我使用实例初始化器的唯一地方就是在一行地图中快速初始化,例如:
Map<String,String> m = new HashMap<String,String>(){{
put("a","b");
put("c","b");
put("d","b");
}};
在让我们说一个接口
中初始化一个地图会很有用interface A {
Map<String,String> PROPS = Collections.unmodifiableMap(new HashMap<String,String>(){{
put("a","b");
put("c","b");
put("d","b");
}});
}
仍然这样做你最终得到了一个HashMap的匿名子类...
答案 2 :(得分:1)
最好重载构造函数并拥有任意数量的构造函数变体。最好的例子是Java的Arraylist。它有两个构造函数。一个以整数作为参数,另一个是默认构造函数。如果你看一下默认的构造函数,它就会使用常量值10来调用Single参数构造函数。
List<Object> x = new ArrayList<Object>(); //Creates with default capacity 10
List<Object> y = new ArrayList<Object>(40); //Creates with the specified capacity 40
答案 3 :(得分:1)
我会留下他们的首选。但基于其他反应,它似乎可能更“自己”。我喜欢它们因为它将相关信息保存在一起。
可以在一个地方完成所有操作,而不是在构造函数中声明值并设置它答案 4 :(得分:0)
您可以使用带参数的构造函数,此构造函数调用私有setter。而不是实现一个默认构造函数,该构造函数使用默认值调用该构造函数。如果要为属性指定默认值,请在声明中执行。
实例和静态初始化器适用于初始化复杂的数据结构,如矩阵或多维数据集。
顺便说一下,最终属性大多称为常量。