You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何抛出可被同方法内其他catch块捕获的异常及修复手机号设置方法的异常处理逻辑

Java中如何抛出可被同方法内其他catch块捕获的异常及修复手机号设置方法的异常处理逻辑

首先我得指出你当前代码的核心问题:在catch (NumberFormatException e)块中抛出的InvalidPhoneNumber异常,根本无法被同一个try-catch结构里的catch (InvalidPhoneNumber e)捕获。

这是因为try-catch的catch分支只能捕获来自try块内部抛出的异常,而catch块本身抛出的异常会直接跳出当前的try-catch结构,向上传递到调用栈,最终导致程序崩溃——这就是你运行代码时输入非数字内容就直接报错终止的原因。

接下来给你两种可行的修复方案,你可以根据自己的需求选择:

方案1:嵌套try-catch,统一异常处理逻辑

通过嵌套try-catch结构,让NumberFormatException转换后的InvalidPhoneNumber异常能被外层的catch捕获,这样所有手机号相关的错误都能复用同一套提示重输的逻辑:

private static void setPhoneNumber(Person person, Scanner scanner) {
    System.out.print("Введите номер телефона в виде целого числа: ");
    String input = scanner.nextLine();
    while (true) {
        try {
            // 内层try负责处理数字解析和手机号设置
            try {
                long phoneNumber = Long.parseLong(input);
                person.setPhoneNumber(phoneNumber);
                break; // 输入正确,跳出循环
            } catch (NumberFormatException e) {
                // 解析失败时,抛出自定义异常统一处理
                throw new InvalidPhoneNumber("Номер телефона должен состоять только из цифр");
            }
        } catch (InvalidPhoneNumber e) {
            // 统一捕获所有InvalidPhoneNumber异常(包括解析失败和set方法抛出的)
            String message = String.format("%s. Повторите ввод: ", e.getMessage());
            System.out.print(message);
            input = scanner.nextLine();
        }
    }
}

方案2:直接处理数字格式错误,避免额外抛出异常

如果你的错误逻辑比较简单,也可以直接在NumberFormatException的catch块中完成提示重输的逻辑,省去嵌套结构,代码更简洁:

private static void setPhoneNumber(Person person, Scanner scanner) {
    System.out.print("Введите номер телефона в виде целого числа: ");
    String input = scanner.nextLine();
    long phoneNumber;
    while (true) {
        try {
            phoneNumber = Long.parseLong(input);
            person.setPhoneNumber(phoneNumber);
            break; // 输入正确,跳出循环
        } catch (NumberFormatException e) {
            // 直接处理非数字输入的提示
            System.out.print("Номер телефона должен состоять только из цифр. Повторите ввод: ");
            input = scanner.nextLine();
        } catch (InvalidPhoneNumber e) {
            // 处理Person类set方法抛出的自定义格式异常
            String message = String.format("%s. Повторите ввод: ", e.getMessage());
            System.out.print(message);
            input = scanner.nextLine();
        }
    }
}

两种方案的对比

  • 方案1的优势是异常处理逻辑统一:所有手机号相关的错误都通过InvalidPhoneNumber异常流转,后续如果新增其他需要抛出该异常的场景,直接复用外层的捕获逻辑即可,扩展性更好。
  • 方案2更简洁直观:避免了嵌套代码,适合当前错误场景较少的情况,阅读和维护成本更低。

修复后再运行代码,当你输入非数字内容(比如df)时,程序会提示你重新输入,而不是直接崩溃,完全符合你的预期。

备注:内容来源于stack exchange,提问作者Альберт Александров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 09:54:29