3 回答

TA贡献1831条经验 获得超9个赞
静态初始化程序对于cletus很有用,我以相同的方式使用它们。如果您有一个静态变量要在加载类时进行初始化,则可以使用静态初始化程序,尤其是因为它允许您执行复杂的初始化操作并且仍然具有静态变量be final。这是一个巨大的胜利。
我发现“ if(someStaticVar == null)//做东西”是混乱且容易出错的。如果它是静态初始化并声明的final,则避免了它的可能性null。
但是,当您说:
静态/实例初始化器可用于设置“最终”静态/实例变量的值,而构造函数无法
我假设您同时在说:
静态初始值设定项可用于设置“最终”静态变量的值,而构造函数不能
实例初始化器可用于设置“最终”实例变量的值,而构造函数不能
而您在第一点上是正确的,在第二点上是错误的。例如,您可以执行以下操作:
class MyClass {
private final int counter;
public MyClass(final int counter) {
this.counter = counter;
}
}
同样,当构造函数之间共享大量代码时,处理此问题的最佳方法之一是链接构造函数,并提供默认值。这很清楚地表明正在做什么:
class MyClass {
private final int counter;
public MyClass() {
this(0);
}
public MyClass(final int counter) {
this.counter = counter;
}
}

TA贡献1784条经验 获得超9个赞
我最经常使用静态初始化程序块来设置最终的静态数据,尤其是集合。例如:
public class Deck {
private final static List<String> SUITS;
static {
List<String> list = new ArrayList<String>();
list.add("Clubs");
list.add("Spades");
list.add("Hearts");
list.add("Diamonds");
SUITS = Collections.unmodifiableList(list);
}
...
}
现在,可以使用单行代码完成此示例:
private final static List<String> SUITS =
Collections.unmodifiableList(
Arrays.asList("Clubs", "Spades", "Hearts", "Diamonds")
);
但是静态版本可以整洁得多,尤其是当这些项目对于初始化而言并非简单时。
天真的实现也可能不会创建不可修改的列表,这是潜在的错误。上面创建了一个不变的数据结构,您可以从公共方法等中愉快地返回。

TA贡献1780条经验 获得超1个赞
只是为了补充一些已经很不错的观点。静态初始化程序是线程安全的。它在加载类时执行,从而使静态数据初始化比使用构造函数更简单,在构造函数中,您将需要一个同步块来检查静态数据是否已初始化,然后进行实际初始化。
public class MyClass {
static private Properties propTable;
static
{
try
{
propTable.load(new FileInputStream("/data/user.prop"));
}
catch (Exception e)
{
propTable.put("user", System.getProperty("user"));
propTable.put("password", System.getProperty("password"));
}
}
与
public class MyClass
{
public MyClass()
{
synchronized (MyClass.class)
{
if (propTable == null)
{
try
{
propTable.load(new FileInputStream("/data/user.prop"));
}
catch (Exception e)
{
propTable.put("user", System.getProperty("user"));
propTable.put("password", System.getProperty("password"));
}
}
}
}
别忘了,您现在必须在类而不是实例级别进行同步。这将为每个构造的实例产生一个成本,而不是在加载类时产生一次成本。另外,这很丑;-)
添加回答
举报