需要输出的解释

时间:2012-02-26 15:28:13

标签: java scjp ocpjp

为什么“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考试。

2 个答案:

答案 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 - 请记住,我们将其设置为无法参考amaina,因此更改仍然存在 - 所以我们打印第一个参数“Hi2”。接下来,我们将static设置为3,因此即将进行的a测试失败。在下一行中,我们首次打印“Hi1”并创建一个a==1的新实例,我假设它是整个代码片段所在的类。

由于PlayingWithMaina,因此即使对于新对象,其值仍为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 [])方法执行两次的原因,这就是为什么从该方法写入的输出会出现两次。