Java 的有个异常设计一直没理解

2020-01-17 09:15:24 +08:00
 matepi

类似

  int i = Integer.parseInt("e");
会抛出
  java.lang.NumberFormatException
  NumberFormatException 的隶属关系
Object
  -Throwable
    -Exception
      -RuntimeException
        -IllegalArgumentExcetipn
          -NumberFormatException

挺正常,捕获 Exception 就能 catch 住他

然而如果这么写

  static int i = Integer.parseInt("e");
会抛出
  java.lang.ExceptionInitializerError ..
 Caused by: java.lang.NumberFormatException ...
而 ExceptionInitializerError 的的隶属关系
Object
  -Throwable
    -Error
      -LinkageError
        -ExceptionInitializerError

这时,捕获 Exception 已经不能 catch 住这个异常了。需要捕获 Throwable 或者 Exception | Error 了。

然而同样都是做了一个Integer.parseInt("e"),这时升格成为 static,就造成了异常类的变化。导致捕获方式的变化。这是不是很奇怪?

当然这里的Integer.parseInt("e"),只是一个例子 如果你有你可爱的同学,在 static 块 /变量里面写了一大段复杂逻辑,搞出各种各样的 Exception,都会被升格成为ExceptionInitializerError。从而不能被 catch Exception 所 catch

从类的初始化过程、从编译的角度貌似能够理解这个 LinkageError。但从具体逻辑的角度,这为啥呢?

其实这个还有一个问题就是有人说到的所谓的异常处理"军规",Never catch Throwable class。这点在这个情况下又如何理解呢?

6709 次点击
所在节点    Java
26 条回复
Raymon111111
2020-01-17 14:34:53 +08:00
抛出来包装了一下

试想你写一个获取用户的接口,结果数据库报了个数据库相关的错误,你肯定得转一下啊
restlessdream
2020-01-17 14:49:50 +08:00
Java 的 Error 类 doc 第一句就是:
An {@code Error} is a subclass of {@code Throwable} that indicates serious problems that a reasonable application
should not try to catch. Most such errors are abnormal conditions.

如果出现 Error 的异常,这个时候就表明是严重错误,必须要进行解决,而不是通过 catch 来忽略掉,上面很多人说了,类加载期间出现异常,那么这个类就是不可用的,这个时候需要去解决代码 bug,而不是去 catch 来忽略掉。
matepi
2020-01-17 15:41:26 +08:00
@restlessdream 没说抓了忽略掉不解决……说的是由于有人真去信了 Never catch Throwable class,造成异常一路到了最外层,都没人抓。导致日志里都找不到 Error 的异常。导致 bug 的难以定位解决。
chendy
2020-01-17 16:02:38 +08:00
“我同样要解决的是“抓到”这个异常之后修正。“
不知道什么类型的项目,如果是 crud 类的全局抓 Throwable 打 log 看一眼 stack trace 就能抓,然后改修修改甩锅甩锅…
matepi
2020-01-17 16:37:11 +08:00
@chendy 不会抓 Throwable,只会抓 Exception,是很多人的习惯。相信这楼里面都有超过一半都是。且希望写全局的人知道抓 Throwable 吧。更多时候只能在自己的代码出口上抓个 Throwable,记下日志,然后继续 throw。
mxalbert1996
2020-01-17 23:49:07 +08:00
这里 never catch 的 catch 指的是狭义的 catch,即 catch 后吞掉,先 catch 写了日志以后再 throw 算 rethrow 吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/638609

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX