2013-03-06 63 views
5

当我可以通过构造函数初始化静态成员时,为什么要使用静态初始化块?为什么我会在java中使用静态初始化块?

+8

如果_never_有一个该类的实例 - 但想使用它的静态函数,它使用由静态初始化块初始化的值,该怎么办? – ppeterka 2013-03-06 11:41:20

+1

和每次调用c'tor时,静态值将被重置。坏!! – Azodious 2013-03-06 11:42:46

回答

3

首先,你可能永远不会有任何类的实例。或者你可能希望在之前让静态成员声明你有任何类的实例。

其次,从构造函数初始化静态成员更多的工作:

  • 你需要确保每一个构造函数做到这一点;
  • 您需要维护一个标志以跟踪静态成员是否已初始化;
  • 你必须考虑同步以防止竞争条件;
  • 您可能不得不考虑同步的性能影响,尤其是当您有许多线程创建您的类的许多实例时。

最后,它通常是错误的做法概念(我说“通常是”因为有延迟初始化合法用途)。

+0

+1 - 尽管如果你打算实现惰性(或非惰性延迟)初始化,你可能不会在构造函数中“发生”。 – 2013-03-06 11:56:09

1

静态成员不与类的任何实例关联,而构造函数创建实例。您可以使用静态成员,而不需要单个类的实例,它们仍然需要初始化。在这种情况下,构造函数不能完成这项工作。

0

那么为什么:如果下面是

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"); 
}}; 
  1. 它引入了一个新的匿名类,在JAR文件;不太理想。
  2. 第二种形式是令人讨厌的游戏。
+0

为什么要引入新的匿名类不是最优的?它会导致类加载错误?或者你只是说你不想膨胀你的罐子。 – 2013-12-15 22:45:37

+1

@DavidT。我对任何一种形式都没有不喜欢,但是比较两者:第一种是多余的“数字”,第二种创建了一个无用的类(很小的开销),并且对于非java开发人员来说有误导性的语法。真正的危险是在Serializable类中使用非静态的'{{...}}'时,周围类的'this'也会被序列化。例如,在重新加载对象后,我遇到过这样的'X.this'。 – 2013-12-16 00:11:00

+1

实际上,我发现了一个区别 - >在Eclipse上,如果在Anonymous类中发生崩溃,Eclipse甚至不知道哪个项目指向崩溃行(比如说,你有一堆线程和可运行的作为匿名类) – 2013-12-16 02:08:53

相关问题