java - Switch语句——JVM内存分配、堆栈溢出

标签 java

我正在学校上 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 就不会存储程序从一种方法到另一种方法的路径。

同样,他没有详细解释,而且他解释的方式听起来很令人困惑(我试图根据他给我的内容尽可能清楚地解释)。过去三个小时我一直在网上寻找任何与他告诉我的内容类似的内容,但我找不到任何内容......所以我决定询问专家。

你们能帮我一下吗?

最佳答案

当计算机执行方法/函数调用时,它必须:

  1. 记住调用函数正在做什么——局部变量的值,以及被调用函数完成时从哪里恢复执行;
  2. 将控制权转移给被调用的函数。

当被调用的函数完成时,它:

  1. 将控制返回到调用函数中记住的位置;在那里,它
  2. 恢复局部变量的值等;和
  3. 继续处理被调用函数返回的值(如果有)。

您的函数系统的问题在于它们可以继续调用而永远不会返回:

mainMenu -> submenu1 -> mainMenu -> subMenu1...等等,等等

如果你的函数永远不会返回,那么每次你进行新的调用时,它都必须记住越来越多的东西,可能在某个时候超过了可用于存储这些东西的(堆栈)内存量,从而导致堆栈溢出错误。

某些语言实现了一种称为“尾部调用优化”的优化,当调用另一个函数是您的函数可以做的最后事情时,它实际上会避免存储这些内容。在这种情况下,它不会再次需要局部变量的值,也不需要记住在哪里恢复,因为它可以在它的调用函数中恢复,而该函数已经被记住了。

在这样的语言中,您的代码实际上可以没问题...但 java 不是这些语言之一。

关于java - Switch语句——JVM内存分配、堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60664917/

相关文章:

java - 如何规范健身分数?

java - JTable Multiarray 中复选框值的 setValueAt

java - 如何判断是哪一个抛出了同类型的异常?

java - 来自 Java 的 Flex 图表的 ArrayCollections

java - 显示数组列表的元素

java - 如何使用 Maven 创建具有依赖项的可执行/可运行 JAR?

java.lang.ArrayIndexOutOfBoundsException : length=4; index=4 length array 异常

java - 我想为 viewpager 页面中的按钮设置一个 onClickListener

java - 部署到 Weblogic 11g 的 Spring Boot 应用程序无法启动

java - 使用改造 2 在回收站 View 上显示项目