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/
JAVA异常使用_每个人都曾用过、但未必都用得好的更多相关文章
- 全面理解Java异常的运行机制
1. 引子 try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解.不过,我亲自体验的“教训”告诉我,这个东西可不是想象中的那么简单.听话. ...
- 讲解java异常
J2EE项目异常处理 为什么要在J2EE项目中谈异常处理呢?可能许多java初学者都想说:“异常处理不就是try….catch…finally吗?这谁都会 ...
- JAVA 异常分类与理解
摘自CSDN:::::http://blog.csdn.net/hguisu/article/details/6155636 1. 引子 try…catch…finally恐怕是大家再熟悉不过的语句了 ...
- 浅谈java异常[Exception]
学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:589809992 我们一起学Java! 一. 异常的定义 在<java编程思想 ...
- 基础知识《十》java 异常捕捉 ( try catch finally ) 你真的掌握了吗?
本文转载自 java 异常捕捉 ( try catch finally ) 你真的掌握了吗? 前言:java 中的异常处理机制你真的理解了吗?掌握了吗?catch 体里遇到 return 是怎么处理 ...
- Java异常之自定义异常
哎呀,妈呀,又出异常了!俗话说:"代码虐我千百遍,我待代码如初恋". 小Alan最近一直在忙着工作,已经很久没有写写东西来加深自己的理解了,今天来跟大家聊聊Java异常.Java异 ...
- 10个关于Java异常的常见问题
这篇文章总结了十个经常被问到的JAVA异常问题: 1.检查型异常VS非检查型异常 简单的说,检查型异常是指需要在方法中自己捕获异常处理或者声明抛出异常由调用者去捕获处理: 非检查型异常指那些不能解决的 ...
- Java 异常讲解(转)
六种异常处理的陋习 你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗? 1 OutputStreamWrite ...
- 浅析Java异常
1.什么是异常 结构不佳的代码不能运行,这是Java的基本理念. 发现错误的理想时机是在编译期.然而,编译器并不能发现所有的错误,余下的问题就需要在程序运行时解决.这就需要错误能通过某种方式,把适当的 ...
随机推荐
- java集合之Map_keySet_entrySet
keySet()的使用:该方法返回的是一个key对象的Set<E>集合,通过该set集合的对象调用iterator方法返回一个迭代器,通过该迭代器可访问到set集合里面的key 再调用Ha ...
- MySQL数据库SQL层级优化
本篇主涉及MySQL SQL Statements层面的优化. 首先,推荐一个链接为万物之始:http://dev.mysql.com/doc/refman/5.0/en/optimization.h ...
- css元素隐藏(display:none和visibility:hidden)
在css中, display:none和visibility:hidden都能够使元素隐藏.但是两者所带来的效果完全不同. css display:none 当使用该样式的时候,HTML元素的宽高等 ...
- zabbix之1监控概念
1.通过通用的snmp监控,无需代理端 2.通过snmp代理 snmp代理的工作原理:在被监控端设置代理,代理不断的获取本地数据,而管理端定期通过代理获取监控数据. snmp目前有v1,v2,v3三种 ...
- H.数7(模拟)
1212: H.数7 时间限制: 1 Sec 内存限制: 64 MB 提交: 8 解决: 5 标签提交统计讨论版 题目描述 数7是一个简单的饭桌游戏,有很多人围成一桌,先从任意一人开始数数,1.2 ...
- javascript跨域获取json数据
项目在开发过程中,用到了天气预报的功能,所以需要调用天气预报的api,一开始以为直接用ajax调用url就可以获取天气数据,结果涉及到了跨域的问题,这里做一个记录. 说到跨域,就得知道同源策略. 同源 ...
- windows环境下搭建Cocos2d-X开发环境
最近终于有时间可心搞搞自己的东西了,呵呵,那就开始做个手机小游戏给孩子玩吧. 首先必须选定开发的框架,移动终端开源的游戏框架貌似不多,找来找去也就这个了,名字简单Cocos2d-X,是Cocos2d国 ...
- PMBOK 项目管理 九大知识领域和五大流程 PMI
Project Management Institute.PMI 是世界上最大的非盈利机构,是项目管理领域的领导者.PMI制定项目管理行业标准,带领项目管理的研究并提供项目管理的培训,证书,还有一些加 ...
- 使用Qt编写服务器端程序(包括Http传输服务器端)的方法
使用Qt编写客户端的程序的示例或demo较多,但是编写服务器端程序的demo很少.当然,服务器端的程序一般不需要带界面,这点我们可以理解.不过有些时候我们还是需要使用Qt编写一个简单的测试用的服务器代 ...
- javascript 之 location.href、跨窗口调用函数
location.href这个东西常常用于跳转,location既是window对象的属性,又是document对象的属性. JavaScript hash 属性 -- 返回URL中#符号后面的内容 ...