【发布时间】:2013-02-21 04:25:57
【问题描述】:
当我可以通过构造函数初始化静态成员时,为什么要使用静态初始化块?
【问题讨论】:
-
如果您从未拥有该类的实例 - 但想使用它的静态函数,它使用由静态初始化块初始化的值,该怎么办?跨度>
-
并且每次调用 c'tor 时,都会重置静态值。糟糕!
当我可以通过构造函数初始化静态成员时,为什么要使用静态初始化块?
【问题讨论】:
首先,你可能永远不会有你的类的任何实例。或者您可能希望在拥有该类的任何实例之前初始化静态成员。
其次,从构造函数初始化静态成员的工作量更大:
最后,在概念上通常是错误的做法(我说“通常”是因为延迟初始化有合法用途)。
【讨论】:
静态成员不与类的任何实例相关联,而构造函数创建实例。您可以在没有类的单个实例的情况下使用静态成员,它们仍然必须被初始化。在这种情况下,构造函数无法完成这项工作。
【讨论】:
那为什么:
static Set<String> digits = new HashSet<String>();
static {
Collections.add(digits, "unu", "du", "tri", "kvar", "kvin");
digits.add("ses");
digits.add("sep");
digits.add("ok");
}
如果以下可能:
static Set<String> digits = new HashSet<String>() {{
Collections.add(this, "unu", "du", "tri", "kvar", "kvin");
add("ses");
add("sep");
add("ok");
}};
【讨论】:
digits 出现,第二种创建了一个任意类(很小的开销),并且对非 Java 开发人员有误导性的语法。真正的危险是在 Serializable 类上使用非静态 {{ ... }} 时:然后周围类的 this 也会被序列化。例如,在重新加载对象后,我遇到过这样的 X.this 为空。