JAVA异常使用_每个人都曾用过、但未必都用得好

一、抛出异常 vs. 返回错误代码

有人说“Well, an exception is a goto.”,但也有人言“makes the code simpler by visibly separating the general case of expected processing from the special cases of errors.”

简单地分析一下两者优劣。异常的优点:让代码更简洁,不再到处if-return;无论CheckedEx还是UnCheckEx都会强迫调用方或系统处理;Exception Chain和继承体系,可以解耦检测错误和错误处理,方便包装异常和控制错误链;异常调试方便,可以跟踪到引发异常的源指令。异常的缺点,除了效率慢之外,最重要的一点是很难知道应该try-catch具体神马。例:

badly exception-based exception

not badly exception-based exception

很难发现因为先初始化Visible=true、在new Icon时抛异常导致错误逻辑的情景。但对于ErrorCode而言,由于大量的if-return、更容易辨识逻辑的正确性。

ErrorCode的优点在于清楚每一个具体的错误类型Code,但你一定不清楚可能捕获多少具体Exception;返回一种结果状态,如0〜成功、-1〜失败;将Error的传播层限制在父层,对于Exception Chain而言,“The thrower of an exception is specifically relinquishing the right to have any expectations about how the exception will be handled.”;易于CodeReview以及保证编写逻辑正确性,被用于编写操作系统、底层驱动等等。但有许多缺点,没有像Exception的链式处理等诸多优点,而且经常忘记检测返回是否成功、需要频繁变更ErrorCode等数据类型。

对于Exception和ErrorCode而言,需要找到两者的平衡点,有以下一些原则:

1、对于绝大部分代码而言,Exception更加安全,到少会有异常体系去处理,再不济也就程序异常 终止;但针对需要well-reviewed的关键代码,适宜采用ErrorCode;

2、如果涉及到与业务逻辑相关的代码,最好采用ErrorCode;业务逻辑无关的代码,如传入参数校验,采用Exception;

3、除了trying之外没有处理逻辑和更多优势的情况,最好采用Exception;

4、远程接口实现中,仅采用ErrorCode。因为远程调用框架对Exception的支持度等具有较大差异。

二、怎样抛出异常&ErrorCode

仅当涉及到业务逻辑错误的情况下抛出异常,注意几点:

1、一个系统中至多有3〜5个具体自定义异常,如ibatis就仅5个左右;

2、如果Caller负责在调用之前检测条件,则应该抛出UnCheckedEx,否则抛出CheckedEx;

3、远程调用一定要try-catch;

4、ErrorCode应该采用Code+String形式,如:

5、return ErrorCode应当采用“{object, error}”的形式,如:

e.g:一个异常体系设计示例

三、参数校验

参数校验,是一类比较容易触发返回ErrorCode或抛Exception的行为。有类规则:

1、Api入参校验采用Exception方式;

2、允许出错的参数校验、采用ErrorCode方式。

参数校验有几类常用包,如:

com.google.common.base.Preconditions

org.springframework.validation.ValidationUtils

org.apache.commons.lang.Validate

不太推荐使用Spring的ValidationUtils,太过依赖Spring框架、向后扩展性不强。Guava库的Preconditions vs. Apache的Validate:

1、Preconditions校验可抛出不同异常,如checkArgument throws IllegalArgumentException、checkNotNull throws NullPointerException等,Validate则仅抛出一种IllegalArgumentException;

2、Message参数,Preconditions适为灵活,Validate不支持StringFormat,如:

Validate.isTrue(i > 0, "Should be positive but was: " + i);

Validate.isTrue(i > 0, "Should be positive but was: ", i);

checkArgument(i > MIN, "Expected more than %s, got %s", MIN, i);

3、集合判断,Apache有几个额外的函数:

  • Validate.notEmpty(Collection collection)

  • Validate.notEmpty(Map map)

  • Validate.notEmpty(Object[] array)

  • Validate.noNullElements(Collection collection)

  • Validate.noNullElements(Object[] array)

而Precondictions使用则比较麻烦:checkArgument(isNotEmpty(list));

4、Precondictions可以一条语句搞定判断后赋值,this.field = checkNotNull(parameter);

5、比较陈旧的系统,推荐使用Validate;

http://c2.com/cgi/wiki?AvoidExceptionsWheneverPossible

http://piotrjagielski.com/blog/google-guava-vs-apache-commons-for-argument-validation/

posted on 2014-02-12 20:17 我思我能 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/icanth/p/3546562.html

JAVA异常使用_每个人都曾用过、但未必都用得好相关推荐

  1. java 异常机制_深入理解Java异常处理机制

    一.引子 try-catch-finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的"教训"告诉我,这个东西可不是想象中 ...

  2. java异常 说服力_异常常见面试题目

    1) Java中什么是Exception? 这个问题经常在第一次问有关异常的时候或者是面试菜鸟的时候问.我从来没见过面高级或者资深工程师的 时候有人问这玩意,但是对于菜鸟,是很愿意问这个的.简单来说, ...

  3. java异常原则_有效处理Java异常三原则

    Java中异常提供了一种识别及响应错误情况的一致性机制,有效地异常处理能使程序更加健壮.易于调试.异常之所以是一种强大的调试手段,在于其回答了以下三个问题: 什么出了错? 在哪出的错? 为什么出错? ...

  4. java 异常对象_在java中的异常处理中的异常对象是什么

    展开全部 Exception类以及他的子类 的一个实例对象 比如32313133353236313431303231363533e58685e5aeb931333264633563 常见异常 1. j ...

  5. java异常机制_全面理解java异常机制

    在理想状态下,程序会按照我们预想的步骤一步一步的执行,但是即使你是大牛,你也不可避免出错,所以java为我们提供了异常机制.本文将会从以下几个方面介绍java中的异常机制: 异常机制的层次结构 异常的 ...

  6. JAVA跨考_考研人的2019——一战跨考清华计算机的血泪史

    2019已经过去好多天了,看到大师傅们纷纷秀出了他们的年终总结,而每年都有积极参与的我,却到现在还迟迟没有写下这段时光,我无法原谅我自己,抱歉,俺太迟了. 考研人的 2019 终究是苦逼的一年,从确定 ...

  7. java 异常国际化_基于springboot实现http响应异常信息国际化

    背景 国际化是指在设计软件,将软件与特定语言及地区脱钩的过程.当软件被移植到不同的语言及地区时,软件本身不用做内部工程上的改变或修正. 本文提到的异常响应信息国际化是指:前端向后台发起请求,后台在处理 ...

  8. java 异常信息_优雅的异常处理 -- Java中的异常

    处理异常自己处理 try-catch抛出让别人处理 throws 获得异常信息 直接打印异常对象 通过异常对象调用getMessage()方法获得 通过异常对象调用printStackTrace()方 ...

  9. java 异常 中英文_史上最全的Java中所有Exception异常中英文对照

    Java中所有Exception异常中英文对照AclNotFoundException, 如果对不存在的访问控制列表进行访问,则会 ArithmeticException 算数异常 ArrayInde ...

最新文章

  1. Unity3d 开发-基础篇
  2. Jackson 序列化对象成 JSON 字符串,忽略部分字段(属性)
  3. Linux下二进制包、源代码包、rpm.binary与rpm.source
  4. SoundStream VS Lyra: 谷歌今年新推出的两款AI音频编解码器有何不同?
  5. 登录,注册,登录,登录..?
  6. 在.Net Core 3.0中尝试新的System.Text.Json API
  7. _Linux结束进程到底有多少种方法?
  8. HDU——1272小希的迷宫(并查集+拓扑排序)
  9. 真传x深度学习第一课:环境配置搭建
  10. Linux内核协议栈分析之网卡初始化——tcp/ip通信并不神秘(1)
  11. 【Win7开启DMA】
  12. 美通企业周刊 | 中国全球化品牌50强榜单发布;酩帝诗威士忌拍出近21万美元天价...
  13. 看linux centos版本信息,Linux CentOS查看操作系统版本信息
  14. c++ 关于heap的STL用法
  15. 软件开发、硬件开发、IPD产品开发 及 工程开发各阶段划分
  16. php openssl函数手册,OpenSSL 函数 - PHP 7 中文文档
  17. C语言指针-什么是指针,如何引用指针
  18. 使用EDTA进行TE注释
  19. vue3 报错提示 找不到模块“./XXX.vue”或其相应的类型声明
  20. 软件获取imei和imsi_imei和imsi

热门文章

  1. 篮球战术谈之1-2-2进攻法
  2. Android 屏幕适配攻略(六)设置通知样图标与启动图标适配
  3. Android自定义控件ImageViwe(四)——多点触控实现图片的自由移动
  4. Android自定义ImageView(二)——实现双击放大与缩小图片
  5. localhost,127.0.0.1,本机IP,三者的区别
  6. 四、Spring中使用@Conditional按照条件注册Bean
  7. 【转】深入分析JAVA IO(BIO、NIO、AIO)
  8. C# MVC 用户登录状态判断
  9. 通过Intel XDK编写跨平台app(二)
  10. 前端基础-git(二):轻松搞定git创建仓库,操作仓库内容