为什么“Hi1”和“Hi3”会被以下代码显示两次?
static int a=1;
public static void main(String[] args) {
if (a==2) { System.out.println(args[0]); a = 3;}
if (a==1) { main(); }
System.out.println("Hi1");
System.out.println(new PlayingWithMain().main("Hi3"));
}
public static void main() {
a = 2;
String[] a = new String[10];
a[0] = "Hi2";
main(a);
}
String main(String s) {
return s;
}
我刚开始准备OCPJP考试。
答案 0 :(得分:2)
这个问题的第一课 - 或诀窍,取决于你如何看待它 - 只有一个main
方法是特殊的,无论有多少main
方法存在。特殊的是采用
public static void main( /* multiple arguments */ ) { ... }
过去,论证必须是String[] args
,但对于最近的版本,var-args也是可以接受的(例如String... args
)。 JLS 12.1.4
现在我们知道要开始的方法,我们看到第一行检查a
的值。我们看到它已初始化为1,因此我们可以忽略a==2
行。然后,在下一行,我们跳转到无参数main
。
在no-arg main
中,a
设置为2.下一课是方法局部变量可以隐藏类变量。声明了一个新的a
,它在方法中优先,但只有方法才有效。它是一个大小为十的字符串数组,但只设置了第一个字符串(“Hi2”)。在这个方法中还有一个教训:编写这段代码是为了让你认为接下来会调用string-arg main
,但它没有,因为我们没有创建一个对象而它不是{{1} }。相反,我们回到static
。
这次,main(String[] args)
为2 - 请记住,我们将其设置为无法参考a
,main
为a
,因此更改仍然存在 - 所以我们打印第一个参数“Hi2”。接下来,我们将static
设置为3,因此即将进行的a
测试失败。在下一行中,我们首次打印“Hi1”并创建一个a==1
的新实例,我假设它是整个代码片段所在的类。
由于PlayingWithMain
为a
,因此即使对于新对象,其值仍为3。但是,由于对象正在调用static
,因此我们不会转到main("Hi3")
版本的static
;相反,我们转到string-arg main
。该方法只是将输入直接踢回调用者,然后立即打印出来。
这是针对string-array-arg main
的,所以我们回到调用它的方法,即无参数main
。它也完成了,所以我们再回到JVM调用的main
版本。记住,我们刚刚完成了这一行
main(String[] args)
所以我们再次打印“Hi1”。最后,我们重复最后一行,创建另一个新的if (a==1) { main(); }
对象并最后一次打印“Hi3”。
答案 1 :(得分:0)
main(String [])调用main(),如果a == 1则再调用main(String []),这在开头是真的。
a变量用于使此递归仅发生一次而不是无休止地发生。
这就是main(String [])方法执行两次的原因,这就是为什么从该方法写入的输出会出现两次。