静态初始化块

据我所知,“静态初始化块”用于设置静态字段的值,如果它不能在一行中完成。

但我不明白为什么我们需要一个特殊的块。例如,我们将一个字段声明为静态(不带值赋值)。然后编写几行代码,生成并向上述声明的静态字段分配一个值。

为什么我们需要在一个特殊的块中包含此行,例如:?static {...}


答案 1

非静态块:

{
    // 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

答案 2

如果它们不在静态初始化块中,它们会在哪里?您将如何声明一个仅用于初始化目的的局部变量,并将其与字段区分开来?例如,您希望如何编写:

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

如果 和 不在块中,它们看起来像字段。如果它们位于一个没有前面的块中,这将被视为实例初始化块而不是静态初始化块,因此它将在每个构造的实例中执行一次,而不是总共执行一次。firstsecondstatic

现在,在这种特殊情况下,您可以改用静态方法:

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

...但是当您希望在同一块中分配多个变量或没有变量时,这不起作用(例如,如果您只想记录某些内容 - 或者可能初始化本机库)。