Java基础:没有名称或返回类型的静态函数

6
public class Main {
    public static final Logger LOGGER = Logger.getLogger(Main.class.getName());

    static {
        try {
             LOGGER.addHandler(new FileHandler("errors.log",true));
        }
        catch(IOException ex) {
             LOGGER.log(Level.WARNING,ex.toString(),ex);
        }
    }
...

我想知道这个无名静态函数是什么。

在我学习的Java中没有看到过这样的东西。

它有什么用处?

通常在什么时候使用?

这将在程序中何时执行?


谢谢大家,不过其实不需要那么多答案 :) - Itako
6个回答

8
那被称为静态块,在初始化期间只会执行一次。此外,如果有多个静态初始化块,则运行时保证它们按照源代码中出现的顺序调用。这里有一个相当不错的解释和一些示例代码。 https://www.geeksforgeeks.org/g-fact-79/

3
您只能通过使用静态块来处理静态成员变量。请注意,即使您多次调用构造函数静态块也仅在JVM上运行一次。
为什么我们需要静态块?因为我们无法在构造函数中初始化我们的静态final成员变量,这没有任何意义。
因此,您可以使用构造函数来初始化静态变量,因为它们是按实例创建的。您应该在静态块中初始化静态final变量。非final静态成员变量的初始化可以写在静态块内部或外部,这是一个选择。如果您希望在每个实例创建时将相同值分配给静态变量,则在构造函数中分配静态变量以重置静态变量。如果您只想设置静态变量一次,即使它不是final成员变量,您也必须在静态块内编写初始化语句。
以下是一个简单的示例:

A-具有静态初始化块的示例模型类

public class SampleModel {

    private int index;                          // Will be init within the constructor
    private static final int MAX_VALUE;         // Will be init within static block
    private static String messageOfTheDay;      // Will be init within static block

    // Argument Constructor
    public SampleModel(int index) { 
        this.index = index;
        System.out.println("Constructor called");
    }

    // static block, will be run only once!
    static {
        System.out.println("WARNING: Static Block called !");

        MAX_VALUE = 69;
        messageOfTheDay = "I'm here";
    }

    public String getMessageOfTheDay() {
        return messageOfTheDay;
    }

    public int getMaxValue() {
        return MAX_VALUE;
    }

    public int getIndex() {
        return index;
    }

}

B - 演示代码

public class StaticBlockDemo {

    public static void main(String[] args) {
        SampleModel obj1 = new SampleModel(1);
        SampleModel obj2 = new SampleModel(2);
        SampleModel obj3 = new SampleModel(3);

        System.out.println();
        System.out.println( "obj1 : index    : " + obj1.getIndex() );
        System.out.println( "obj1 : Max Value: " + obj1.getMaxValue() );
        System.out.println( "obj1 : Max MOTD : " + obj1.getMessageOfTheDay() + "\n");

        System.out.println( "obj2 : index    : " + obj2.getIndex() );
        System.out.println( "obj2 : Max Value: " + obj2.getMaxValue() );
        System.out.println( "obj2 : Max MOTD : " + obj2.getMessageOfTheDay() + "\n");

        System.out.println( "obj3 : index    : " + obj3.getIndex() );
        System.out.println( "obj3 : Max Value: " + obj3.getMaxValue() );
        System.out.println( "obj3 : Max MOTD : " + obj3.getMessageOfTheDay() + "\n");

    }

}

C - 输出

WARNING: Static Block called !
Constructor called
Constructor called
Constructor called

obj1 : index    : 1
obj1 : Max Value: 69
obj1 : Max MOTD : I'm here

obj2 : index    : 2
obj2 : Max Value: 69
obj2 : Max MOTD : I'm here

obj3 : index    : 3
obj3 : Max Value: 69
obj3 : Max MOTD : I'm here

注意,在输出结果中,构造函数被调用了3次,但是静态块只被调用了一次。


3

这段代码在类加载时只执行一次。在这个特定的例子中,它为应用程序设置了一个日志记录器。


0

这是一个静态初始化块,它在类加载时运行一次。它可以用于初始化静态成员变量。


0

这是一个静态初始化器,它将在类初始化期间执行。正如您所看到的,它允许您在该阶段运行复杂的逻辑,包括异常处理。


0

这是一个初始化块,在类加载时调用。


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