调用没有名字的Java方法
我正在看下面的代码,发现有点奇怪:
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 "); } }
我会希望这给编译错误,因为System.out
与“Y”不属于一个方法声明只是一个{ }
。 为什么这是有效的? 我不明白这个代码是如何被调用的。
当运行它时,它也会产生xycg
,为什么在序列构造函数之前调用static { }
?
这个:
static { System.out.print("x "); }
是一个静态初始化块 ,并且在加载类时调用。 你可以在你的课堂上尽可能多的按照他们的外貌(从上到下)执行。
这个:
{ System.out.print("y "); }
是一个初始化块 ,代码复制到类的每个构造函数的开头。 所以如果你的类有很多构造函数,并且他们都需要在开始时做一些共同的事情,那么你只需要编写一次代码,并把它放在一个像这样的初始化块中 。
因此,你的输出是完全合理的。
正如Stanley在下面评论的,请参阅Oracle教程中有关描述初始化块的部分以获取更多信息。
它不是一个方法,而是一个初始化块 。
{ System.out.print("y "); }
它将在构造函数调用之前执行。 而
static { System.out.print("x "); }
是静态的初始化块 ,当类由类加载器加载时执行。
所以当你运行你的代码
1.类由类加载器加载,所以执行静态初始化块
输出:打印x
2.创build对象以便执行初始化块,然后调用构造器
输出:y打印后跟c
3.调用main方法,然后调用go方法
输出:g被打印
最终输出:xycg
这可能有助于http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/
这是一个实例初始化块,后面跟着一个静态初始化块 。
{ System.out.print("y "); }
在创build类的实例时被调用。
static { System.out.print("x "); }
在类加载器加载类时被调用。 所以,当你这样做
new Sequence().go();
该类被加载,所以它执行static {}
,然后执行实例初始化块{}
,然后调用构造函数的主体,然后执行新创build的实例上的方法。 Ergo输出xycg
。
static { System.out.print("x "); }
是一个静态块,并在类加载期间被调用
{ System.out.print("y "); }
是一个初始化块
您可以在一个类中有多个初始化块,在这种情况下,它们按照它们出现在类中的顺序执行。
请注意,类中的任何初始化块都在构造函数之前执行。
static { System.out.print("x "); }
是一个由类共享的初始化块(如static
),它是首先执行的。
{ System.out.print("y "); }
是类的所有对象(构造函数)共享的初始化块,接下来是。
Sequence() { System.out.print("c "); }
是类的一个特殊的构造函数,它是第三个执行的。 每次执行构造函数时,都会首先调用实例初始化块。 这就是“y”在“c”之前的原因。
void go() { System.out.print("g "); }
只是一个与使用上面的构造函数构造的对象关联的实例方法,这是最后一个。
{ System.out.print("y "); }
这些块被称为initializer block
。 每次创build一个class
的实例时都会执行它。 在编译时,这个代码被移动到你的类的每个构造函数中。
在static initializer
块的情况下:
static { System.out.println("x "); }
它在加载类时执行一次。 我们一般使用static
初始化块来初始化一个static
字段,需要多个步骤。
它用作初始化块 ,在任何静态声明之后运行。 它可以用来确保没有其他人可以像Singletondevise模式一样创build类的实例(以相同的方式使用私有构造函数)。
static { System.out.print("x "); }
当JRE 加载并初始化类时, Static blocks
只执行一次。
每当你创build一个新的实例时 ,就会调用non-static
块,它将在构造函数之前调用。
因为在这里你只创build了一个Sequence
实例,所以在non-static
块之后调用了这个实例,然后调用了实际上你的目标的方法。