原文地址:https://dzone.com/articles/catch-me-if-you-cant-do-otherwise

I don't know whether it's an anti-pattern or just a common and very popular mistake, but I see it everywhere and simply must write about it. I'm talking about exception catching without re-throwing. I'm talking about something like this Java code:

try {

  stream.write(data);

} catch (IOException ex) {

  ex.printStackTrace();

}

©Catch Me If You Can (2002) by Steven Spielberg

Pay attention: I don't have anything against this code:

try {

  stream.write('X');

} catch (IOException ex) {

  throw new IllegalStateException(ex);

} 

This is called exception chaining and is a perfectly valid construct.

So what is wrong with catching an exception and logging it? Let's try to look at the bigger picture first. We're talking about object-oriented programming — this means we're dealing with objects. Here is how an object (its class, to be exact) would look:

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();

    }

  }

}

Here is how I'm using this class:

new Wire(stream).send(1);

Looks nice, right? I don't need to worry about that IOException when I'm calling send(1). It will be handled internally, and if it occurs, the stacktrace will be logged. But this is a totally wrong way of thinking, and it's inherited from languages without exceptions, like C.

Exceptions were invented to simplify our design by moving the entire error handling code away from the main logic. Moreover, we're not just moving it away but also concentrating it in one place — in themain() method, the entry point of the entire app.

The primary purpose of an exception is to collect as much information as possible about the error and float it up to the highest level, where the user is capable of doing something about it. Exception chaining helps even further by allowing us to extend that information on its way up. We are basically putting our bubble (the exception) into a bigger bubble every time we catch it and re-throw. When it hits the surface, there are many bubbles, each remaining inside another like a Russian doll. The original exception is the smallest bubble.

When you catch an exception without re-throwing it, you basically pop the bubble. Everything inside it, including the original exception and all other bubbles with the information inside them, are in your hands. You don't let me see them. You use them somehow, but I don't know how. You're doing something behind the scenes, hiding potentially important information.

If you're hiding that from me, I can't promise my user that I will be honest with him and openly report a problem when it occurs. I simply can't trust your send() method anymore, and my user will not trust me.

By catching exceptions without re-throwing them, you're basically breaking the chain of trust between objects.

My suggestion is to catch exceptions as seldomly as possible, and every time you catch them, re-throw.

Unfortunately, the design of Java goes against this principle in many places. For example, Java has checked and un-checked exceptions, while there should only be checked ones in my opinion (the ones you must catch or declare as throwable). Also, Java allows multiple exception types to be declared as throwable in a single method — yet another mistake; stick to declaring just one type. Also, there is a generic Exception class at the top of the hierarchy, which is also wrong in my opinion. Besides that, some built-in classes don't allow any checked exceptions to be thrown, like Runnable.run(). There are many other problems with exceptions in Java.

But try to keep this principle in mind and your code will be cleaner: catch only if you have no other choice.

P.S. Here is how the class should look:

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);

  }

}

转载于:https://www.cnblogs.com/davidwang456/p/4655284.html

Catch Me If You ... Can't Do Otherwise--转载相关推荐

  1. 异常 try catch finally return 执行关系 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. PHP的Reflection反射机制

    原文地址: http://www.nowamagic.net/php/php_Reflection.php PHP5添加了一项新的功能:Reflection.这个功能使得程序员可以 reverse-e ...

  3. 在vs2005中使用Jmail发送邮件问题

    jmail.Message Jmail = new jmail.Message(); DateTime t = DateTime.Now;             String Subject = & ...

  4. 微信授权获取用户的openid和支付宝授权获取用户的userid

    为什么80%的码农都做不了架构师?>>>    当一请求一个链接或者是扫描二维码时,会请求后台方法,当然对于微信和支付宝来说,大多数时候是扫 码 一.首先说微信: 1.首先会判断请求 ...

  5. 连接ORACLE实例

    public class OracleConn { public static Connection getConn() { Connection conn = null;   try {       ...

  6. 使用JAVA开发微信公众平台(一)——环境搭建与开发接入

    转自:https://www.cnblogs.com/jerehedu/p/6377759.html 一. 初始微信公众平台 微信公众平台,即我们平时所说的"公众号",曾用名&qu ...

  7. Hibernate5-命名查询

    1.创建项目,项目名称hibernatedemo21,目录结构如图所示 2.在项目中创建lib目录存储jar文件,目录结构如图所示 3.在src目录中创建实体类Forum,包名(com.mycompa ...

  8. C#代码实现把网页文件保存为mht文件

    MHT叫"web单一文件".顾名思义,就是把网页中包含得图片,CSS文件以及HTML文件全部放到一个MHT文件里面.而且浏览器可以直接读取得. 由于项目需要,需实现把指定的网页文件 ...

  9. JAVA(IO流)知识整理

    IO (Input Output)流 IO流用来处理设备之间的数据传输: JAVA对数据的操作是通过流的方式: JAVA对于操作流的对象都在IO包中: 流按操作数据分为两种:字节流和字符流: 流按流向 ...

  10. redis增删改查封装

    2019独角兽企业重金招聘Python工程师标准>>> import java.util.ArrayList; import java.util.HashSet; import ja ...

最新文章

  1. 王者荣耀中有哪些获胜率高的玩法?
  2. 使用SAP CRM中间件从ERP下载Customer的错误消息:Customer classification does not exist
  3. python堆排序求topn_Java堆排序,取得前TopN个数
  4. Apache CXF 3.0:JAX-RS 2.0和Bean验证1.1最终一起
  5. CSS:盒子模型和清除float浮动的三种常用方法
  6. 视觉SLAM笔记(46) 基本的 VO
  7. python带参数怎么运行_如何运行带参数的python脚本
  8. CentOS 7伪分布式方式安装Hadoop-2.6.0-cdh5.6.0并且通过主机浏览器访问hadoop工作台
  9. 邓小铁:博弈论研究中的学术快乐
  10. ORA-01045: user lacks CREATE SESSION privilege
  11. java过滤器的作用_javaweb过滤器的作用,过滤器filter的作用是什么?
  12. node的HTPP请求
  13. 在阿里云OSS,如何更好搭建自己的云储存
  14. 总结30个Python赚钱的接单平台!兼职月入5000+,成年人的世界,钱是活下去的筹码
  15. 王者荣耀高清壁纸脚本Python文件
  16. [教程]centos7.x 及centos8 硬盘安装法#免U盘#采坑记
  17. Java程序猿必学第十一篇——接口
  18. Java获取Prometheus监控指标数据
  19. 谢孟媛老师英语拼读03(附我备注)
  20. java老版手机游戏合集破解

热门文章

  1. mysql安全无密码登录_技术分享 | 安全地无密码登录 MySQL
  2. C++中的虚函数与纯虚函数
  3. import export php,import与export在node.js中的使用方法
  4. 华为手机如何关闭通知栏推送消息_如果华为手机升级EMUI10后,电池耗电很快!要记得调整这3个设置...
  5. 运行时权限+读取系统联系人
  6. c++ 新建一个数组
  7. Leetcode 344. 反转字符串 (每日一题 20210812)
  8. pandas 补充笔记:转换提取类型
  9. TImm 笔记: 训练模型
  10. 机器学习笔记:Adam