Java 需要对输出进行解释吗
为什么以下代码会显示两次“Hi1”和“Hi3”Java 需要对输出进行解释吗,java,scjp,ocpjp,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 PlayingWithM
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考试。main(String[])调用main(),如果a==1,它将再次调用main(String[]),这在开始时是正确的
a变量用于使这种递归只发生一次,而不是无休止地发生
这就是main(String[])方法被执行两次的原因,也是从该方法写入的输出出现两次的原因。这个问题的第一课——或者说诀窍,取决于您如何看待它——是只有一个
main
方法是特殊的,不管存在多少main
方法。特殊的一个是采取这种形式的一个
public static void main( /* multiple arguments */ ) { ... }
过去,参数必须是String[]args
,但对于最新版本,变量args也是可以接受的(例如String…args
)
现在我们知道了从哪个方法开始,我们看到第一行检查a
的值。我们看到它被初始化为1,因此我们可以忽略a==2
行。然后,在下一行,我们跳转到无参数main
在no argmain
中,a
设置为2。下一课是方法局部变量可以隐藏类变量。一个新的A
被声明,它在方法内部具有优先权,但只在方法存在的时间内存在。它是一个大小为10的字符串数组,但只设置了第一个字符串(设置为“Hi2”)。这个方法还有一个教训:编写这段代码是为了让您认为接下来会调用字符串argmain
,但它不会,因为我们没有创建对象,它也不是静态的。相反,我们回到main(String[]args)
这一次,a
是2-记住,我们在no argmain
中设置它,a
是静态的
,所以更改会一直存在-所以我们打印第一个参数“Hi2”。接下来,我们将a
设置为3,因此即将进行的a==1
测试失败。在下一行中,我们第一次打印“Hi1”,并创建一个新的PlayingWithMain
实例,我假设它是整个代码片段所在的类
由于a
是静态的
,因此即使对于新对象,其值也保持为3。但是,由于对象正在调用main(“Hi3”)
,因此我们不会转到main
的静态版本;相反,我们转到字符串argmain
。该方法只是将输入直接返回给调用者,然后立即打印出来
对于字符串数组argmain
,它就是这样做的,所以我们回到调用它的方法,即no-argmain
。它也完成了,所以我们再次回到JVM调用的main(String[]args)
版本。记住,我们刚刚完成了这一行
if (a==1) { main(); }
所以我们又开始打印“Hi1”。最后,我们重复最后一行,这将创建另一个新的PlayingWithMain
对象,并最后一次打印“Hi3”。只需用笔和纸跟踪执行。(顺便说一句,这段代码很糟糕。)或者你可以使用任何IDE(如eclipse、netbeans等)调试程序。这将帮助你更容易理解。如果按照流程进行,控件将首先转到main(),因为a==1 ecevaluates为true,然后返回main(String[]args),现在a==2 evaluates为true,显示Hi2,然后显示Hi1和Hi3。根据我的说法,代码执行应该在这里结束。但我仍然无法理解为什么会显示最后一个Hi1和Hi3。