调用没有名称的Java方法

时间:2012-12-04 08:52:13

标签: java initializer

我正在查看下面的代码,发现有点奇怪的事情:

public class Sequence {
    Sequence() {
        System.out.print("c ");
    }

    {
        System.out.print("y ");
    }

    public static void main(String[] args) {
        new Sequence().go();
    }

    void go() {
        System.out.print("g ");
    }

    static {
        System.out.print("x ");
    }
}

我希望这会产生编译错误,因为带有“y”的System.out不属于仅{ }的方法声明。为什么这个有效?我不知道这个代码是如何被调用的。

运行它时它也产生x y c g,为什么在序列构造函数之前调用static { }

8 个答案:

答案 0 :(得分:147)

此:

static {
        System.out.print("x ");
    }

静态初始化块,并在加载类时调用。您可以根据需要在课堂上拥有尽可能多的课程,并按照外观(从上到下)执行。

此:

    {
        System.out.print("y ");
    }

初始化块,代码被复制到类的每个构造函数的开头。因此,如果您的类中有许多构造函数,并且它们都需要在开始时执行一些常见操作,则只需编写一次代码并将其放在初始化块中。

因此你的输出很有意义。

Stanley所述,请参阅the section in the Oracle tutorial describing initializaiton blocks了解详情。

答案 1 :(得分:25)

它不是一种方法,而是初始化块

 {
    System.out.print("y ");
 }

它将在构造函数调用之前执行。 而

static {
        System.out.print("x ");
       }

静态初始化块,它是在类加载器加载类时执行的。

所以当你运行你的代码时 1.类由类加载器加载,因此执行静态初始化块 输出:x打印
2.创建对象,以便执行初始化块,然后调用constuctor 输出:y打印后跟c
3.调用main方法,然后调用go方法
输出:g打印

最终输出:x y c g
这可能会有助http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/

答案 2 :(得分:16)

这是实例初始化块,后跟静态初始化块

{
    System.out.print("y ");
}
在创建类的实例时会调用

static {
    System.out.print("x ");
}
当类加载器加载类时,会调用

。所以当你这样做时

new Sequence().go();

该类被加载,因此它执行static {},然后执行实例初始化块{},然后调用构造函数的主体,然后调用新创建的实例上的方法。输出x y c g

答案 3 :(得分:15)

static {
        System.out.print("x ");
    }

静态块并在类加载期间调用

{
    System.out.print("y ");
}

初始化块

您可以在一个类中有多个初始化块,在这种情况下,它们按照它们在类中出现的顺序执行。

请注意,类中存在的任何初始化块都在构造函数之前执行。

答案 4 :(得分:10)

static {
      System.out.print("x ");
}

是由类共享的初始化块(由static表示),它首先被执行。

{
        System.out.print("y ");

}

是该类的所有对象(构造函数)共享的初始化块,接下来是。

Sequence() {
        System.out.print("c ");
}

是类的特定构造函数,它是第三个执行的。每次执行构造函数时,都会首先调用实例初始化块。这就是“y”出现在“c”之前的原因。

void go() {
        System.out.print("g ");
}

只是一个与使用上面构造函数构造的对象关联的实例方法,它最后出现。

答案 5 :(得分:9)

{
    System.out.print("y ");
}

这些类型的块称为 initializer block 。每次创建class的实例时都会执行该操作。 在编译时,此代码将移动到您的类的每个构造函数中。

static initializer 阻止的情况: -

static {
    System.out.println("x ");
}

在加载类时执行一次。 我们通常在初始化static字段时使用static初始化程序块,需要多个步骤。

答案 6 :(得分:6)

它用作初始化块,并在任何静态声明之后运行。它可用于确保没有其他人可以像 Singleton 设计模式一样创建类的实例(与使用私有构造函数的方式相同)。

答案 7 :(得分:3)

static {
    System.out.print("x ");
}

Static blocks仅在加载类时执行一次并由JRE初始化。

non-static阻止将在每次创建新实例时调用,并且它将在构造函数之前调用。

在这里,你只创建了Sequence的{​​1}个实例,这个实例在non-static块之后被调用,然后是实际上你的目标的方法。