捕获异常并重新抛出它,但这不是异常

2023-12-21

我偶然发现代码看起来像这样:

void run() {
    try {
        doSomething();
    } catch (Exception ex) {
        System.out.println("Error: " + ex);
        throw ex;
    }
}

void doSomething() {
    throw new RuntimeException();
}

这段代码让我感到惊讶,因为它看起来像run()-方法能够抛出一个Exception,因为它捕获了Exception然后重新抛出它,但该方法未声明为抛出Exception显然不需要。这段代码编译得很好(至少在 Java 11 中)。

我的期望我必须声明throws Exception in the run()-method.

额外的信息

以类似的方式,如果doSomething被宣布抛出IOException那么只有IOException需要在run()-方法,尽管Exception被抓住并被重新扔掉。

void run() throws IOException {
    try {
        doSomething();
    } catch (Exception ex) {
        System.out.println("Error: " + ex);
        throw ex;
    }
}

void doSomething() throws IOException {
    // ... whatever code you may want ...
}

Question

Java通常喜欢清晰,这种行为背后的原因是什么?一直都是这样吗? Java 语言规范中允许的内容run()方法不需要声明throws Exception在上面的代码片段中? (如果我添加它,IntelliJ 会警告我Exception永远不会被抛出)。


我还没有扫描过JLS正如您在问题中所问的,所以请对这个答案持保留态度。我想发表评论,但它太大了。


我有时觉得好笑,怎么办javac在某些情况下(例如您的情况)非常“聪明”,但留下了很多其他事情需要稍后处理JIT。在这种情况下,只是编译器“可以告诉”只有一个RuntimeException会被抓住的。这是显而易见的,这是你唯一扔进去的东西doSomething。如果您将代码稍微更改为:

void run() {
    try {
        doSomething();
    } catch (Exception ex) {
        Exception ex2 = new Exception();
        System.out.println("Error: " + ex);
        throw ex2;
    }
}

你会看到不同的行为,因为现在javac可以说有一个新的Exception你扔出的东西与你接住的东西无关。

但事情远非理想,您可以通过以下方式再次“欺骗”编译器:

void run() {
    try {
        doSomething();
    } catch (Exception ex) {
        Exception ex2 = new Exception();
        ex2 = ex;
        System.out.println("Error: " + ex);
        throw ex2;
    }
}

国际海事组织,因为ex2 = ex;它不应该再次失败,但它确实失败了。

以防万一这是用编译的javac 13+33

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

捕获异常并重新抛出它,但这不是异常 的相关文章

随机推荐

  • 纯文本文档的字符编码未声明 - mootool 脚本

    我刚刚注意到有一个warning当我在 FireFox 浏览器上查看 mootool js 脚本时 会弹出消息 警告消息是 纯文本文档的字符编码未声明 文档在某些浏览器中会呈现乱码 如果文档包含来自外部的字符 则配置 US ASCII 范围
  • 在 Sonata 管理列表中使用自定义列

    我使用 Symfony 4 1 创建了一个项目 并安装了 Sonata Admin Bundle 在我的类别列表中 我尝试添加与类别字段不相关的列 所以我做了 Admin CategoryAdmin php protected functi
  • 类成员和显式堆栈/堆分配

    假设我们有 4 个类 如下所示 class A public A void m B private B m B class B public B void m i 1 private int m i class C public C voi
  • TextView文本缩小到给定宽度

    我的活动中有一个文本视图字段 其字体大小为 16 其文本是通过代码设置的 假设如果我有一个大文本 它应该缩小该数据 即字体大小减小 而不是转到下一行 我该怎么做
  • Visual Basic 中的屏幕尺寸

    如何在 Visual Basic 中访问屏幕尺寸 我在网上查看过 它说要使用 Screen width 和 Screen length 但它无法识别这些属性 有什么提示吗 在VB中你可以使用Screen Width and Screen H
  • pl/sql - 集合可以循环遍历列名吗?

    以下代码的输出是 LAT MISC SID NO MIN LENGTH 1 2 1 1 MAX LENGTH 6 6 4 2 输出正如我所期望的那样 但是无论如何都可以使用索引 即j 循环遍历列而不是执行RESULTS I 最长长度 结果
  • 如何使用 Azure Functions 解析表单数据

    我正在尝试在 Azure 函数中获取表单数据 public static async Task
  • 使用指令类静态函数?

    我正在使用一个具有lot名为的类中的函数TCODConsole作为静态函数 现在我认为它在命名空间中 所以我写道 using namespace TCODConsole 然后我发现TCODConsole不是命名空间 而是类 有没有一种方法可
  • 在 Java 中,在一个子类中将变量设置为 Final 和 static,同时在其他子类中保持变量不变

    我有一个超类和两个扩展它的子类 我想初始化一个名为 radius 的变量 它可以在子类 A 中自由设置 但对于子类 B 总是相同的 我可以在每次创建对象 B 时初始化该变量 但我想知道是否可以使子类 B 中的变量 final 和 stati
  • Angular 12 中复选框更改处理函数的 Jasmine 测试

    我正在尝试编写用于复选框更改的简单测试函数 但无法运行它 错误在于 Spec 没有期望 并且处理函数未包含在代码覆盖率中 模板
  • 带分页的 Spring-Data FETCH JOIN 不起作用

    我正在尝试使用 HQL 获取我的实体以及使用 JOIN FETCH 的子实体 如果我想要所有结果 则效果很好 但如果我想要页面 则情况并非如此 我的实体是 Entity Data public class VisitEntity Id Au
  • 我应该将解决方案和功能保持 1:1 的比例吗?

    我有一个包含多个事件接收器和工作流的复杂共享点部署 我还对现有列表进行架构更改 添加新的元数据列并更改现有列 我应该将单个功能 事件接收器或工作流程打包到单个解决方案中 还是应该将多个功能放入单个解决方案中 因为它们都可以协同工作 我问的一
  • Numpy zip 函数

    例如 如果我有两个 numpy 一维数组 x np array 1 2 3 y np array 11 22 33 如何将它们压缩到 Numpy 2D 坐标数组中 如果我做 x1 x2 x3 zip x y 结果是列表类型 而不是 Nump
  • 使用owin中间件和IdentityServer v3刷新令牌

    我最近设置了 IdentityServer v3 它的运行就像梦一样 但是我在使用 OWIN 中间件时遇到了麻烦 我想使用混合流 这样我就可以在后端刷新令牌 而无需用户重定向回 IdentityServer 来每 5 分钟获取一个新的访问令
  • 如何获取Python Pillow(PIL)版本?

    我想得到PIL https pypi python org pypi PIL安装在 Mac OS X 计算机上的 Python 成像库 版本 我之前安装过Pillow https pypi python org pypi Pillow PI
  • 无法在 java12 中创建字符串对象列表

    List al Arrays asList ABC XYZ 这段代码在 Java 11 中运行良好 但当我在 Java 12 中尝试此代码时 出现错误 我缺少什么提示吗 谢谢您的帮助 所要求的最少代码 import java util Ar
  • 将 Angular 验证指令与 Breeze 结合使用会阻止任何无效输入

    如果将任何用于验证的角度指令 ng minlength ng maxlength ng pattern 等 添加到绑定到微风实体的输入 如果发现无效 它将阻止任何用户输入 如果 ng model 中的值最初是有效的 则会显示出来 但如果将该
  • 通过 Windows cgo->gcc->ld 的 DLL 链接给出“未定义的引用(函数)”错误

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 非常详细的
  • 根据不同的概率获取数组的随机项?

    好吧 想象一下我正在用 JavaScript 创建一个 Pokemon 游戏 我有一个这样的对象 pokemon pikachu hp 100 probability 0 1 squirtle hp 90 probability 0 2 我
  • 捕获异常并重新抛出它,但这不是异常

    我偶然发现代码看起来像这样 void run try doSomething catch Exception ex System out println Error ex throw ex void doSomething throw ne