据我所知,“静态初始化块”是用来设置静态字段的值,如果它不能在一行中完成。
但我不明白为什么我们需要一种特殊的积木。例如,我们将一个字段声明为静态(没有赋值)。然后写几行代码,生成并赋值给上面声明的静态字段。
为什么我们需要这些行在一个特殊的块,如:static{…}?
据我所知,“静态初始化块”是用来设置静态字段的值,如果它不能在一行中完成。
但我不明白为什么我们需要一种特殊的积木。例如,我们将一个字段声明为静态(没有赋值)。然后写几行代码,生成并赋值给上面声明的静态字段。
为什么我们需要这些行在一个特殊的块,如:static{…}?
当前回答
在静态块中构造对象之前,可以为一个类执行一次代码。
E.g.
class A {
static int var1 = 6;
static int var2 = 9;
static int var3;
static long var4;
static Date date1;
static Date date2;
static {
date1 = new Date();
for(int cnt = 0; cnt < var2; cnt++){
var3 += var1;
}
System.out.println("End first static init: " + new Date());
}
}
其他回答
作为补充,就像@Pointy说的
“静态”部分中的代码将在类加载时执行 时间,在构造类的任何实例之前(以及在 任何静态方法都从其他地方调用)。
它应该将System.loadLibrary("I_am_native_library")添加到静态块中。
static{
System.loadLibrary("I_am_a_library");
}
它将保证在相关库加载到内存之前不调用本机方法。
根据oracle的loadLibrary:
如果使用相同的库名多次调用此方法, 第二次和随后的调用将被忽略。
所以很意外地,把系统。不使用loadLibrary以避免库被多次加载。
static int B,H;
static boolean flag = true;
static{
Scanner scan = new Scanner(System.in);
B = scan.nextInt();
scan.nextLine();
H = scan.nextInt();
if(B < 0 || H < 0){
flag = false;
System.out.println("java.lang.Exception: Breadth and height must be positive");
}
}
如果你的静态变量需要在运行时设置,那么一个静态{…} block非常有用。
例如,如果您需要将static成员设置为存储在配置文件或数据库中的值。
当您想要向静态Map成员添加值时也很有用,因为您不能在初始成员声明中添加这些值。
有几个实际的原因,它必须存在:
初始化静态final成员,其初始化可能引发异常 用计算值初始化静态final成员
人们倾向于使用静态{}块作为一种方便的方式来初始化类在运行时所依赖的东西——比如确保特定的类被加载(例如JDBC驱动程序)。这可以通过其他方式来实现;然而,我上面提到的两件事只能用静态{}块这样的构造来完成。
重要的是要理解类在运行时从java.class.Class实例化。这是执行静态块的时候,这允许你在不实例化类的情况下执行代码:
public class Main {
private static int myInt;
static {
myInt = 1;
System.out.println("myInt is 1");
}
// needed only to run this class
public static void main(String[] args) {
}
}
结果是myInt是1打印到控制台。