我正在查看下面的代码,发现有点奇怪的事情:
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 { }
?
答案 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
块之后被调用,然后是实际上你的目标的方法。