关于递归,您首先要了解的是,您正在执行相同的方法,但您并没有在其中跳跃。你得到不同的处决。让我们从没有递归的简单开始:
public void a() {
System.out.println(">> before b()");
b();
System.out.println("<< after b()");
}
public void b() {
System.out.println(">>>> in b() <<<<");
}
当您致电a() 时:
在 b() 之前打印 >>。
致电b()。
在 b() 中打印 >>> 。
完成b()的执行。
返回a()并打印。
完成a()的执行。
因此,当您调用一个方法时,当前的方法会等待调用完成然后继续。对b() 的调用嵌套在a() 中。
在递归的情况下,会发生同样的事情,但您调用的是相同的方法,而不是 不同的 方法。从本质上讲,您会获得执行和等待的方法的不同版本,您不会跳过同一个。因此,通过递归调用,您会得到如下结果:
您调用recur(3) 并执行该方法。
它打印is0 m之前的K是:3
该方法调用recur(2),这是一个递归调用。此时你得到以下状态:
public int recur(int m) {/* m = 2 */
if(m == 0) {
return 2;
}
int k = 0;
System.out.println("The K before is"+ k+" m is:"+m);
k = recur(m - 1)+1; // <-- stop and wait for this to finish
System.out.println("The K AFTER is"+ k+" m is:"+m);
return k;
}
现在您获得了方法执行的全新副本。这称为recur(2)。
它打印 is0 m 之前的 K is:2
该方法调用recur(2),这是一个递归调用。此时你得到以下状态:
public int recur(int m) {/* m = 3 */ | public int recur(int m) {/* m = 2 */
if(m == 0) { | if(m == 0) {
return 2; | return 2;
} | }
int k = 0; | int k = 0;
System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m);
k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1; // <-- stop and wait for this to finish
System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m);
return k; | return k;
} | }
现在您获得了方法执行的全新副本。这称为recur(1)。
它打印 is0 m 之前的 K is:1
该方法调用recur(0),这是一个递归调用。此时你得到以下状态:
public int recur(int m) {/* m = 3 */ | public int recur(int m) {/* m = 2 */ | public int recur(int m) {/* m = 1 */
if(m == 0) { | if(m == 0) { | if(m == 0) {
return 2; | return 2; | return 2;
} | } | }
int k = 0; | int k = 0; | int k = 0;
System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m);
k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1; // <-- stop and wait for this to finish
System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m);
return k; | return k; | return k;
} | } | }
现在您获得了方法执行的全新副本。这称为recur(0)。
这次执行进入if 语句,因为条件已满足。一切解决之前的最终状态:
public int recur(int m) {/* m = 3 */ | public int recur(int m) {/* m = 2 */ | public int recur(int m) {/* m = 1 */ | public int recur(int m) {/* m = 0 */
if(m == 0) { | if(m == 0) { | if(m == 0) { | if(m == 0) {
return 2; | return 2; | return 2; | return 2; // <-- return and finish
} | } | } | }
int k = 0; | int k = 0; | int k = 0; | int k = 0;
System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m);
k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1;
System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m);
return k; | return k; | return k; | return k;
} | } | } | }
最后,嵌套调用由内而外解析。
recur(0) 完成。返回2。计算recur(0)+1 的结果最终可以继续并分配结果k。现在陈述:
public int recur(int m) {/* m = 3 */ | public int recur(int m) {/* m = 2 */ | public int recur(int m) {/* m = 1 */
if(m == 0) { | if(m == 0) { | if(m == 0) {
return 2; | return 2; | return 2;
} | } | }
int k = 0; | int k = 0; | int k = 0;
System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m);
k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1; // <-- recur(m - 1) = 2
System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m);
return k; | return k; | return k;
} | } | }
K AFTER is3 m is:1 打印出来。
recur(1) 完成。返回3。计算recur(1)+1 的结果最终可以继续并分配该结果k。现在陈述:
public int recur(int m) {/* m = 3 */ | public int recur(int m) {/* m = 2 */
if(m == 0) { | if(m == 0) {
return 2; | return 2;
} | }
int k = 0; | int k = 0;
System.out.println("The K before is"+ k+" m is:"+m); | System.out.println("The K before is"+ k+" m is:"+m);
k = recur(m - 1)+1; /*<-- still waiting for this to finish*/ | k = recur(m - 1)+1; // <-- recur(m - 1) = 3
System.out.println("The K AFTER is"+ k+" m is:"+m); | System.out.println("The K AFTER is"+ k+" m is:"+m);
return k; | return k;
} | }
K AFTER is4 m is:2 打印出来。
recur(2) 完成。返回4。计算recur(2)+1 的结果最终可以继续并分配结果k。现在陈述:
public int recur(int m) {/* m = 3 */
if(m == 0) {
return 2;
}
int k = 0;
System.out.println("The K before is"+ k+" m is:"+m);
k = recur(m - 1)+1; // <-- recur(m - 1) = 4
System.out.println("The K AFTER is"+ k+" m is:"+m);
return k;
}
K AFTER is5 m is:3 打印出来。
对recur(3) 的初始调用结束。
因此,从另一个方法启动的对方法的每次调用都会启动嵌套执行。然后执行首先解决内部,然后继续执行外部。每个调用都有自己的状态 - 如果您在调试器中跟随它似乎就像执行移动到方法的开头,但实际上您现在处于与旧的完全不同的执行中一个。