Java try/catch捕获StringIndexOutOfBoundsException未生效问题
问题根因
你的异常捕获逻辑失效核心原因非常明确:StringIndexOutOfBoundsException 根本不是在你包裹的input.nextLine()读取输入阶段抛出的。Scanner.nextLine()的作用只是读取整行用户输入存到字符串对象里,不管用户输1位还是3位,这行代码都能正常执行,不会触发任何字符串下标越界错误。
真正触发越界的是try块外面的字符串拆分逻辑:
for (int countInternal = 0; countInternal < 4; countInternal++) { guessNum[countInternal] = guess.substring(countInternal, countInternal + 1); }
当用户输入长度不足4位时,循环执行到下标超过输入字符串实际长度的位置,substring方法才会抛出越界异常,但这段代码完全在你的try/catch覆盖范围之外,异常自然不会被捕获,会直接导致程序崩溃。
除此之外现有输入处理还有两个明显逻辑缺陷:
- 检测到输入包含空格时直接调用
System.exit(0)终止整个程序,不符合交互逻辑,正常应该提示用户错误后允许重新输入 - 没有覆盖输入长度超过4位、输入包含非1-9字符的非法场景,这类输入同样会导致逻辑错误或者程序崩溃
修复方案
- 调整try/catch的覆盖范围,不要只包裹读取输入的单行代码,需要把输入校验、字符串拆分的全流程都纳入覆盖范围
- 优先用主动校验替代纯异常捕获做输入合法性判断:先判断输入长度是否为4位、是否全是1-9的数字、是否包含空格,校验不通过直接提示后重输,不消耗猜题次数,这种写法逻辑更直观,也不容易出现捕获范围遗漏的问题
- 非法输入时通过循环+
continue跳过当前轮次剩余的猜题判定逻辑,回到输入环节让用户重新提交,不要直接终止程序
修正后的核心输入处理代码
直接替换原有6次猜题循环内的输入相关逻辑即可,后续的提示生成、胜负判定、文件读写逻辑可以保持原有实现:
for (int count = 0; count < 6; count++) { boolean validInput = false; // 内循环保证输入合法才进入猜题判定流程 while (!validInput) { System.out.println("请输入4位1-9之间的数字作为猜测,输入不要包含空格"); guess = input.nextLine(); // 逐次做合法性校验 if (guess.contains(" ")) { System.out.println("错误:输入不能包含空格,请重新输入"); continue; } if (guess.length() != 4) { System.out.println("错误:输入必须是4位数字,请重新输入"); continue; } if (!guess.matches("[1-9]{4}")) { System.out.println("错误:输入只能包含1-9的数字,请重新输入"); continue; } validInput = true; } // 输入校验通过后再拆分字符串,这里不会再触发下标越界 for (int countInternal = 0; countInternal < 4; countInternal++) { guessNum[countInternal] = guess.substring(countInternal, countInternal + 1); } // 以下保留你原有的hint生成、文件读写、胜负判定逻辑即可 // ... }
补充说明:如果你希望保留异常捕获的写法,只需要把拆分字符串的for循环移入原try块的覆盖范围,也能拦住越界错误,但依然建议搭配主动校验使用,避免其他边界场景触发异常。
内容的提问来源于stack exchange,提问作者DJ Arkaiid
相关产品推荐
相关产品推荐

