据我所知,“静态初始化块”是用来设置静态字段的值,如果它不能在一行中完成。
但我不明白为什么我们需要一种特殊的积木。例如,我们将一个字段声明为静态(没有赋值)。然后写几行代码,生成并赋值给上面声明的静态字段。
为什么我们需要这些行在一个特殊的块,如:static{…}?
据我所知,“静态初始化块”是用来设置静态字段的值,如果它不能在一行中完成。
但我不明白为什么我们需要一种特殊的积木。例如,我们将一个字段声明为静态(没有赋值)。然后写几行代码,生成并赋值给上面声明的静态字段。
为什么我们需要这些行在一个特殊的块,如:static{…}?
当前回答
如果你的静态变量需要在运行时设置,那么一个静态{…} block非常有用。
例如,如果您需要将static成员设置为存储在配置文件或数据库中的值。
当您想要向静态Map成员添加值时也很有用,因为您不能在初始成员声明中添加这些值。
其他回答
静态块用于任何以动态方式初始化静态数据成员的技术,或者我们可以说静态数据成员的动态初始化使用静态块,因为对于非静态数据成员初始化,我们有构造函数,但没有任何地方可以动态初始化静态数据成员
Eg:-class Solution{
// static int x=10;
static int x;
static{
try{
x=System.out.println();
}
catch(Exception e){}
}
}
class Solution1{
public static void main(String a[]){
System.out.println(Solution.x);
}
}
现在我的静态int x将动态初始化..Bcoz时,编译器将去解决方案。因此,我们可以动态地初始化静态数据成员。
}
作为补充,就像@Pointy说的
“静态”部分中的代码将在类加载时执行 时间,在构造类的任何实例之前(以及在 任何静态方法都从其他地方调用)。
它应该将System.loadLibrary("I_am_native_library")添加到静态块中。
static{
System.loadLibrary("I_am_a_library");
}
它将保证在相关库加载到内存之前不调用本机方法。
根据oracle的loadLibrary:
如果使用相同的库名多次调用此方法, 第二次和随后的调用将被忽略。
所以很意外地,把系统。不使用loadLibrary以避免库被多次加载。
非静态块:
{
// Do Something...
}
每次构造类的实例时调用。静态块只被调用一次,当类本身初始化时,不管你创建了多少这种类型的对象。
例子:
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
重要的是要理解类在运行时从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打印到控制台。
这里有一个例子:
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”被省略了。