0

下面的代码为什么会显示两次“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 考试。

4

2 回答 2

2

这个问题的第一课——或技巧,取决于你如何看待它——是只有一种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,我假设它是整个代码片段所在的类。

由于ais 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”。

于 2012-02-27T20:35:09.137 回答
0

main(String[]) 调用 main(),如果 a==1,main() 再次调用 main(String[]),这在开始时为真。

a 变量用于使这种递归只发生一次,而不是无休止地发生。

这就是 main(String[]) 方法执行两次的原因,也是该方法写入的输出出现两次的原因。

于 2012-02-26T15:40:20.687 回答