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/
转载于:https://www.cnblogs.com/icanth/p/3546562.html
JAVA异常使用_每个人都曾用过、但未必都用得好相关推荐
- java 异常机制_深入理解Java异常处理机制
一.引子 try-catch-finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的"教训"告诉我,这个东西可不是想象中 ...
- java异常 说服力_异常常见面试题目
1) Java中什么是Exception? 这个问题经常在第一次问有关异常的时候或者是面试菜鸟的时候问.我从来没见过面高级或者资深工程师的 时候有人问这玩意,但是对于菜鸟,是很愿意问这个的.简单来说, ...
- java异常原则_有效处理Java异常三原则
Java中异常提供了一种识别及响应错误情况的一致性机制,有效地异常处理能使程序更加健壮.易于调试.异常之所以是一种强大的调试手段,在于其回答了以下三个问题: 什么出了错? 在哪出的错? 为什么出错? ...
- java 异常对象_在java中的异常处理中的异常对象是什么
展开全部 Exception类以及他的子类 的一个实例对象 比如32313133353236313431303231363533e58685e5aeb931333264633563 常见异常 1. j ...
- java异常机制_全面理解java异常机制
在理想状态下,程序会按照我们预想的步骤一步一步的执行,但是即使你是大牛,你也不可避免出错,所以java为我们提供了异常机制.本文将会从以下几个方面介绍java中的异常机制: 异常机制的层次结构 异常的 ...
- JAVA跨考_考研人的2019——一战跨考清华计算机的血泪史
2019已经过去好多天了,看到大师傅们纷纷秀出了他们的年终总结,而每年都有积极参与的我,却到现在还迟迟没有写下这段时光,我无法原谅我自己,抱歉,俺太迟了. 考研人的 2019 终究是苦逼的一年,从确定 ...
- java 异常国际化_基于springboot实现http响应异常信息国际化
背景 国际化是指在设计软件,将软件与特定语言及地区脱钩的过程.当软件被移植到不同的语言及地区时,软件本身不用做内部工程上的改变或修正. 本文提到的异常响应信息国际化是指:前端向后台发起请求,后台在处理 ...
- java 异常信息_优雅的异常处理 -- Java中的异常
处理异常自己处理 try-catch抛出让别人处理 throws 获得异常信息 直接打印异常对象 通过异常对象调用getMessage()方法获得 通过异常对象调用printStackTrace()方 ...
- java 异常 中英文_史上最全的Java中所有Exception异常中英文对照
Java中所有Exception异常中英文对照AclNotFoundException, 如果对不存在的访问控制列表进行访问,则会 ArithmeticException 算数异常 ArrayInde ...
最新文章
- Unity3d 开发-基础篇
- Jackson 序列化对象成 JSON 字符串,忽略部分字段(属性)
- Linux下二进制包、源代码包、rpm.binary与rpm.source
- SoundStream VS Lyra: 谷歌今年新推出的两款AI音频编解码器有何不同?
- 登录,注册,登录,登录..?
- 在.Net Core 3.0中尝试新的System.Text.Json API
- _Linux结束进程到底有多少种方法?
- HDU——1272小希的迷宫(并查集+拓扑排序)
- 真传x深度学习第一课:环境配置搭建
- Linux内核协议栈分析之网卡初始化——tcp/ip通信并不神秘(1)
- 【Win7开启DMA】
- 美通企业周刊 | 中国全球化品牌50强榜单发布;酩帝诗威士忌拍出近21万美元天价...
- 看linux centos版本信息,Linux CentOS查看操作系统版本信息
- c++ 关于heap的STL用法
- 软件开发、硬件开发、IPD产品开发 及 工程开发各阶段划分
- php openssl函数手册,OpenSSL 函数 - PHP 7 中文文档
- C语言指针-什么是指针,如何引用指针
- 使用EDTA进行TE注释
- vue3 报错提示 找不到模块“./XXX.vue”或其相应的类型声明
- 软件获取imei和imsi_imei和imsi
热门文章
- 篮球战术谈之1-2-2进攻法
- Android 屏幕适配攻略(六)设置通知样图标与启动图标适配
- Android自定义控件ImageViwe(四)——多点触控实现图片的自由移动
- Android自定义ImageView(二)——实现双击放大与缩小图片
- localhost,127.0.0.1,本机IP,三者的区别
- 四、Spring中使用@Conditional按照条件注册Bean
- 【转】深入分析JAVA IO(BIO、NIO、AIO)
- C# MVC 用户登录状态判断
- 通过Intel XDK编写跨平台app(二)
- 前端基础-git(二):轻松搞定git创建仓库,操作仓库内容