除非万不得已,别 Catch!(万万不得已的意思解释)

网友投稿 859 2022-09-24

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

除非万不得已,别 Catch!(万万不得已的意思解释)

对异常只捕获但并未重新抛出究竟是 anti-pattern,还是个普通而且非常流行的错误确实无从考究。但毫无疑问的是,在所有异常捕获代码中,它基本无处不在,正如下面这段代码:

try { stream.write('X');} catch (IOException ex) { throw new IllegalStateException(ex);}

那么,捕获异常并记录究竟存在什么样的问题?首先,从宏观着手,这里正在谈论的是面向对象编程——意味着需要处理的是对象。一个对象(准确的说,是它的类)应该是这个样子:

final class Wire { private final OutputStream stream; Wire(final OutputStream stm) { this.stream = stm; } public void send(final int data) { try { this.stream.write(x); } catch (IOException ex) { ex.printStackTrace(); } }}

这里这样来应用这个类的:

new Wire(stream).send(1);

看起来不错,对么?当调用 send(1) 时,并不需要担心出现 IOException ,它将在方法内部处理。同时,如果出现异常,异常信息会被记录。但是这么做的理念是完全错误的,它传承自没有异常处理的语言,比如 C。

异常的发明是为了将整个错误处理代码从主要逻辑中移除,以此来简化设计。同时,它们不仅仅是被移走,而且被集中在一个地方——在 main() 方法中,即整个应用的入口。

一个异常的主要目的是搜集尽可能多的错误信息并将它抛到最上层,在这里用户能够针对它做一些处理。Exception chaining 则可以帮助更多,它允许在异常抛至上层的过程中扩充错误信息。在这个过程中,实际上非常类似于每次捕获到泡泡(即异常)后,所做的只是将它添加到一个更大的泡泡中然后重新抛出。当它到达最高层的时候,那里就有许多泡泡,像一个 Russian Doll,一个嵌套着另外一个。最原始的异常就是最小的那个泡泡。

当捕获一个异常而并没有重新抛出时,等同于你捏碎了这个泡泡。其中包含的大量信息,包括最原始的异常和所有其它带有信息的泡泡,都被你牢牢的抓在手中。你杜绝为上层呈现它,同时你如何处理和使用上层也毫无察觉。这一切都像是暗箱操作,一些潜在的重要信息被隐藏。

因此,在这里直接导致的是 send() 方法无法得到信任,同样基于 send() 方法的操作也无法得到信任,对象之间的信任链被破坏殆尽。这里的建议是尽可能少捕获异常,同时一旦捕获则必须抛出。

但是尝试记住这些原则,你的代码将会更加整洁:catch 除非你别无选择。

P.S.这个类应该是这个样子:

final class Wire { private final OutputStream stream; Wire(final OutputStream stm) { this.stream = stm; } public void send(final int data) throws IOException { this.stream.write(x); }}

上一篇:聊聊产品经理那点事(产品经理和业务经理)
下一篇:有关npm rum的3个简洁技巧(有关学习的名言)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~