这个问题的第一课——或技巧,取决于你如何看待它——是只有一种main
方法是特殊的,不管有多少main
方法存在。特殊的是采取形式的
public static void main( /* multiple arguments */ ) { ... }
过去,参数必须是String[] args
,但对于最近的版本,var-args 也是可以接受的(例如String... args
)。 JLS 12.1.4
现在我们知道从哪个方法开始,我们看到第一行检查a
. 我们看到它被初始化为 1,所以我们可以忽略该a==2
行。然后,在下一行,我们跳转到 no-argument main
。
在 no-argmain
中,a
设置为 2。下一课是方法局部变量可以隐藏类变量。一个新a
的被声明,它在方法内部具有优先权,但只与方法一样存在。这是一个大小为 10 的字符串数组,但仅设置了第一个字符串(设置为“Hi2”)。这个方法还有一个教训:编写这段代码是为了让你认为 string-argmain
会被调用,但它没有,因为我们还没有创建一个对象,它不是static
。相反,我们回到main(String[] args)
.
这一次,a
是 2——记住,我们将它设置在 no-argmain
中,a
所以static
变化会持续存在——所以我们打印第一个参数“Hi2”。接下来,我们设置a
为 3,因此即将进行的a==1
测试失败。在下一行中,我们第一次打印“Hi1”并创建 的新实例PlayingWithMain
,我假设它是整个代码片段所在的类。
由于a
is static
,即使对于新对象,它的值也保持为 3。但是,由于对象正在调用main("Hi3")
,我们不会转到 ; 的static
版本main
。相反,我们转到 string-arg main
。该方法只是将输入直接踢回调用者,然后立即打印出来。
这对 string-array-arg来说是这样的main
,所以我们回到调用它的方法 no-arg main
。它也完成了,所以我们再次回到main(String[] args)
JVM 调用的版本。记住,我们刚刚完成了这条线
if (a==1) { main(); }
所以我们继续打印“Hi1”。最后,我们重复最后一行,创建另一个新PlayingWithMain
对象并最后一次打印“Hi3”。