话不多说,先上嵌套函数的代码:
public class TestDemo5 {
public static void main(String[] args) {
System.out.println("main开始");
m1();
System.out.println("main结束");
}
public static void m1(){
System.out.println("m1开始");
m2();
System.out.println("m1结束");
}
public static void m2(){
System.out.println("m2开始");
System.out.println("m2结束");
}
}
输出结果:
main开始
m1开始
m2开始
m2结束
m1结束
main结束
函数的执行流程:
先执行主函数,输出main函数开始,紧接着在主函数里调用了m1()方法,进入m1方法体,执行System.out.println(“m1开始”);语句,输出m1开始,然后调用了m2()函数,进入m2函数体,输出 m2开始 和 m2结束,此时函数已经全部调用完毕,返回主函数体,执行调用m1()方法后的代码块,输出了main函数结束。到此,程序执行完毕,产生结果:
main开始
m1开始
m2开始
m2结束
m1结束
main结束
产生先调用后结束的表面原因
表面上是函数没执行完而不会进行向下执行,所以造成了嵌套函数调用时先调用后结束的结果。
实际原因
在程序的执行过程中,主函数作为程序的入口,先先从主函数开始执行,JVM会调用main函数,生成一个main函数的栈帧,存放在JVM栈中的最下边,然后由main函数调用了m1函数,m1生成一个m1函数的栈帧,存放在JVM栈中,在main函数栈帧之上,而后又由m1调用m2,m2函数生成了m2函数的栈帧,存放在JVM栈中m1栈帧之上。
此时JVM栈中从上到下分别存放着m2栈帧、m1栈帧、main函数栈帧。我们知道,栈是先进后出,所以先出栈的是m2栈帧,而后是m1栈帧,最后一个是main函数栈帧,因此,m2函数先执行完,而后是m1函数,最后是主函数。
至此,我们可以明白为何嵌套函数先调用后结束。