我发现在 Java 中有一个名为 static block
的特性,它包含在类首次加载时执行的代码(我不明白 'loaded' 是什么意思,它是否意味着初始化)。为什么要在静态块内做初始化而不是在构造函数中呢?我的意思是,即使构造函数也做同样的事情,在类第一次初始化时完成所有必要的工作。是否有任何静态块可以完成而构造函数无法完成的任务?
我发现在 Java 中有一个名为 static block
的特性,它包含在类首次加载时执行的代码(我不明白 'loaded' 是什么意思,它是否意味着初始化)。为什么要在静态块内做初始化而不是在构造函数中呢?我的意思是,即使构造函数也做同样的事情,在类第一次初始化时完成所有必要的工作。是否有任何静态块可以完成而构造函数无法完成的任务?
在构造函数中初始化静态字段是一个大错误。是的,你可以在构造函数中初始化静态字段。然而,每次创建对象时静态字段都会重置它们的值。
public class StaticExample {
static int myStaticField;
public StaticExample(){
myStaticField = 10;
}
}
public class Solution {
public static void main(String[] args) {
StaticExample obj1 = new StaticExample();
StaticExample.myStaticField+= 80;
// this will print 90
System.out.println(StaticExample.myStaticField);
// creating new object will reset the static field
StaticExample obj2 = new StaticExample();
// this will print 10
System.out.println(StaticExample.myStaticField);
}
}
这是静态字段意外和不被接受的行为。如果你现在将初始化步骤从构造函数改为静态块,你将得到正确的值。
public class StaticExample {
static int myStaticField;
static {
myStaticField = 10;
}
}
public class Solution {
public static void main(String[] args) {
StaticExample obj1 = new StaticExample();
StaticExample.myStaticField+= 80;
// this will print 90
System.out.println(StaticExample.myStaticField);
// creating new object will NOT reset the static field
StaticExample obj2 = new StaticExample();
// this will print 90
System.out.println(StaticExample.myStaticField);
}
}
public class Board {
public static final Iterable<Location> LOCATIONS;
// set up LOCATIONS
static {
ArrayList<Location> l = new ArrayList<Location>(NUM_ROWS * NUM_COLS);
for (int r = 0; r < NUM_ROWS; r++)
for (int c = 0; c < NUM_COLS; c++)
l.add(new Location(r,c));
LOCATIONS = l;
}
}
main
方法并不会在每次创建类的实例时运行。它只会在显式调用时(就像任何其他静态方法一样)或 JVM 启动应用程序时运行。 - Thorn G