我正在学校上 Java 类(class)。我们的任务是设计一个类作为菜单,并带有多个子菜单。
结构有点像这样(下面的伪代码,只是为了显示结构):
public static void mainMenu() {
switch(integer variable){
case 1: submenu1();
break;
case 2: submenu2();
break;
}
}
public static void submenu1() {
switch(integer variable){
case 1: subsubmenu1();
break;
case 2: subsubmenu2();
break;
default: mainMenu(
}
}
public static void subsubmenu1() {
switch(integer variable) {
case 1: anothersubmenu1()
break;
case 2: anothersubmenu2();
break;
default: submenu1();
}
}
我的问题是:我的老师说这是错误的,因为JVM在内存中存储了程序从一个地方到另一个地方的路径,如果我这样做,从长远来看这会导致堆栈溢出。他没有完全解释它,他只是说我应该使用 boolean 变量用 while 循环包围整个事情,添加一个选项来翻转该 boolean 值以退出 while 循环,因为这样 Java 就不会存储程序从一种方法到另一种方法的路径。
同样,他没有详细解释,而且他解释的方式听起来很令人困惑(我试图根据他给我的内容尽可能清楚地解释)。过去三个小时我一直在网上寻找任何与他告诉我的内容类似的内容,但我找不到任何内容......所以我决定询问专家。
你们能帮我一下吗?
最佳答案
当计算机执行方法/函数调用时,它必须:
- 记住调用函数正在做什么——局部变量的值,以及被调用函数完成时从哪里恢复执行;
- 将控制权转移给被调用的函数。
当被调用的函数完成时,它:
- 将控制返回到调用函数中记住的位置;在那里,它
- 恢复局部变量的值等;和
- 继续处理被调用函数返回的值(如果有)。
您的函数系统的问题在于它们可以继续调用而永远不会返回:
mainMenu -> submenu1 -> mainMenu -> subMenu1...等等,等等
如果你的函数永远不会返回,那么每次你进行新的调用时,它都必须记住越来越多的东西,可能在某个时候超过了可用于存储这些东西的(堆栈)内存量,从而导致堆栈溢出错误。
某些语言实现了一种称为“尾部调用优化”的优化,当调用另一个函数是您的函数可以做的最后事情时,它实际上会避免存储这些内容。在这种情况下,它不会再次需要局部变量的值,也不需要记住在哪里恢复,因为它可以在它的调用函数中恢复,而该函数已经被记住了。
在这样的语言中,您的代码实际上可以没问题...但 java 不是这些语言之一。
关于java - Switch语句——JVM内存分配、堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60664917/