静态初始化器 vs 实例初始化器 vs 构造函数

13

我正在学习有关Java的考试。 在学习过程中,我遇到了一些对我不熟悉的Java语法,例如在类主体内没有名称的花括号({})以及一些带有静态关键字的语法。 我发现它们被称为“初始化器”。 有人能帮我指出它们之间的关键差异以及它们与构造函数的区别吗? 谢谢。


我向你推荐这本书http://www.apress.com/9781430247647,第三章和第四章。 - Leo
@Reieus 他也问到了关于匿名代码块的问题。 - jeremyjjbrown
3个回答

34

它们之间的主要区别在于它们执行的顺序不同。为了说明这一点,我将用一个例子来解释:

public class SomeTest {

    static int staticVariable;
    int instanceVariable;        

    // Static initialization block:
    static {
        System.out.println("Static initialization.");
        staticVariable = 5;
    }

    // Instance initialization block:
    {
        System.out.println("Instance initialization.");
        instanceVariable = 10;
    }

    // Constructor
    public SomeTest() {
        System.out.println("Constructor executed.");
    }

    public static void main(String[] args) {
        new SomeTest();
        new SomeTest();
    }
}

输出结果为:

Static initalization.
Instance initialization.
Constructor executed.
Instance initialization.
Constructor executed.

简单来说:

  • 静态初始化块在JVM加载类时运行一次。
  • 实例初始化块在每次实例化对象之前运行构造函数之前运行。
  • 构造函数(显然)在每次实例化对象时运行。

10
这是一个很好的回答。但是我想补充一点,构造函数比实例初始化器更常用。我认为实例初始化器的主要用途是在匿名内部类中进行初始化,因为它们没有名称,无法拥有构造函数。 - Chris Rice
非常简单而且不错的例子 +1 - Simon Guo

1

构造函数在创建一个类的新实例时只被调用一次。构造函数中初始化的值属于实例的范围。每个实例可以在构造函数中初始化相同字段的不同值。

静态初始化器适用于在静态类中执行设置代码和在枚举中填充数据结构。它们只被调用一次,在类加载到JVM时从上到下按顺序执行,数据存在于类或枚举的作用域内。所有对该类的引用都将返回在静态初始化器中初始化的字段相同的值。

未命名花括号是匿名代码块,可以将引用名称作用域限定在其中。如果在块内创建引用,则无法在块外获得该引用的值。如果你发现需要使用它们,这表明你需要将代码重构为更多的方法。


“Unnamed Curly Braces” 被称为 instance initializers - Edward J Beckett

-2

这是你真正需要查阅教科书才能得到答案的事情。不过我可以给你一些指引。自从我编写Java以来已经过了一些年头,所以我提供给你的信息是通用的。

通常带有花括号的无名块是匿名函数。静态初始化器初始化所有实例都全局可见的数据,并在第一次引用该类时运行一次。你需要小心使用静态属性或方法。有了这些信息,你可以在教材中找到准确的细节。


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