Java中静态块的必要性

60

我发现在 Java 中有一个名为 static block 的特性,它包含在类首次加载时执行的代码(我不明白 'loaded' 是什么意思,它是否意味着初始化)。为什么要在静态块内做初始化而不是在构造函数中呢?我的意思是,即使构造函数也做同样的事情,在类第一次初始化时完成所有必要的工作。是否有任何静态块可以完成而构造函数无法完成的任务?


3
当类被类加载器加载时调用一次,而不是每次实例化类时都调用。 - Wolfgang Kuehn
2
请查看以下 Oracle 官方 Java 教程的章节:了解实例和类成员初始化字段。如果您仍有疑问,请回来咨询。 - Anthony Accioly
1
初始化代码(类加载时间)-> Main(应用程序入口点)-> 构造函数:这里有一个工作示例以进一步说明这一点。 - Anthony Accioly
1
@Cupidvogel main 方法并不会在每次创建类的实例时运行。它只会在显式调用时(就像任何其他静态方法一样)或 JVM 启动应用程序时运行。 - Thorn G
是的,看起来非常复杂。我需要花费相当多的时间和精力来消化它。 - SexyBeast
显示剩余9条评论
13个回答

1
静态块在没有创建实例的情况下必须执行某些操作时非常有用,例如,用非静态值初始化静态变量。

0

在构造函数中初始化静态字段是一个大错误。是的,你可以在构造函数中初始化静态字段。然而,每次创建对象时静态字段都会重置它们的值

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);
  }
}

0
如果你想完全理解技术概念(在这种情况下是Java中静态块的使用),你可能需要在真实应用中找到对这个概念的参考。让我在这里附上一个链接到Gomoku游戏实现的存储库的链接,其中在"Board.java"类中使用了静态块来初始化一个静态字段"Location"
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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接