问题
据我所知,"静态初始化块"用于设置静态字段的值,如果不能在一行中完成的话。
但我不明白为什么我们需要一个特殊的块。例如,我们将一个字段声明为静态(没有值赋值)。然后编写几行代码,生成并为上面声明的静态字段赋值。
为什么我们需要在一个特殊的块中使用这些行:static {...}
?
#1 热门回答(362 赞)
然后静态块:
{
// Do Something...
}
每次构造an类的实例时,都会调用。无论你创建的那种类型的对象有多少,当静态类本身被初始化时,静态块一次被称为****。
例:
public class Test {
static{
System.out.println("Static");
}
{
System.out.println("Non-static block");
}
public static void main(String[] args) {
Test t = new Test();
Test t2 = new Test();
}
}
这打印:
Static
Non-static block
Non-static block
#2 热门回答(114 赞)
如果它们不在静态初始化块中,它们会在哪里?为了初始化的目的,你如何声明一个仅仅是本地的变量,并将其与字段区分开来?例如,如何写:
public class Foo {
private static final int widgets;
static {
int first = Widgets.getFirstCount();
int second = Widgets.getSecondCount();
// Imagine more complex logic here which really used first/second
widgets = first + second;
}
}
Iffirst
和second
不是一块,它们看起来像是田地。如果它们位于前面没有static
的块中,那么它将被视为实例初始化块而不是静态初始化块,因此每个构造实例将执行一次,而不是总共执行一次。
现在在这种特殊情况下,你可以使用静态方法:
public class Foo {
private static final int widgets = getWidgets();
static int getWidgets() {
int first = Widgets.getFirstCount();
int second = Widgets.getSecondCount();
// Imagine more complex logic here which really used first/second
return first + second;
}
}
...但是当你希望在同一个块中分配多个变量时,这不起作用,或者没有(例如,如果你只想记录某些内容 - 或者可能初始化本机库)。
#3 热门回答(89 赞)
这是一个例子:
private static final HashMap<String, String> MAP = new HashMap<String, String>();
static {
MAP.put("banana", "honey");
MAP.put("peanut butter", "jelly");
MAP.put("rice", "beans");
}
"静态"部分中的代码将在类加载时执行,然后构造类的任何实例(并且在从其他地方调用任何静态方法之前)。这样你就可以确保类资源都可以使用了。
也可以使用非静态初始化程序块。这些行为类似于为类定义的构造函数方法的扩展。它们看起来就像静态初始化块一样,除了关闭"static"关键字。