Java异常处理原则与技巧总结
一 处理原则
Java异常代码中我们使用异常的目的是让异常的异常类型来提示“什么”被抛出了--- 即出了什么问题;用异常的栈打印信息来跟踪异常在“哪里”抛出 --- 即哪里出了问题;
异常提示信息来提示“为什么”会抛出 --- 即出问题的原因。在对异常进行处理时,遵循以下原则可以有助于在调试过程中最大限度的使用好异常。
- 具体明确
- 提早抛出
- 延迟捕获
1.具体明确
具体明确指的是在抛出异常时需要针对具体问题来抛出异常,抛出的异常要足够具体详细;在捕获异常时需要对捕获的异常进行细分,这时会有多个catch语句块,这几个catch块中间泛化程度越低的异常需要越放在
前面捕获,泛化程度高的异常捕获放在后面,这样的好处是如果出现异常可以近可能得明确异常的具体类型是什么。
例如 FileInputStream 的一个构造方法如下, 对file对象做检查后判断file是否有效,如果无效直接抛出FileNotFoundException,而不是IOException或者其他更宽泛的Exception
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name);
}
同样的,在对异常做捕获处理时,也需要做到具体明确,以下try语句块中read()和close方法均会抛出IOException而FileInputStream()抛出的是FileNotFoundException
事实上FileNotFoundException继承自IOException,用一个IOException 就可以囊括所有的异常,这里仍然使用了两个catch块来分别捕获,为的就是方便定位异常问题。
public void foo1(String fileName){
File file = new File(fileName);
InputStream in = null;
try {
in = new FileInputStream(file);
Integer num = in.read();
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
2.提早抛出
提早抛出的基本目的还是为了防止问题扩散,这样出现异常的话排查起来会比较耗时,比较典型的一种情况是 NPE(NullPointerException),当某个参数对象为null时,如果不提早判断并抛出异常的话,这个null可能
会藏的比较深,等到出现NPE时就需要往回追溯代码了。这样就给排查问题增加了难度。所以我们的处理原则是出现问题就及早抛出异常。
例如 上面FileInputStream 的构造方法,在使用前就对File 的path做了判断,如果为null 就及早的抛出NullPointerException,防止在后面open方法中传入一个null,从而简化了出现异常的情况,方便定位问题。
3.延迟捕获
延迟捕获说的是对异常的捕获和处理需要根据当前代码的能力来做,如果当前方法内无法对异常做处理,即使出现了检查异常也应该考虑将异常抛出给调用者做处理,如果调用者也无法处理理论上他也应该继续上抛,
这样异常最终会在一个适当的位置被catch下来,而比起异常出现的位置,异常的捕获和处理是延迟了很多。但是也避免了不恰当的处理。
二 处理技巧
对于异常的处理,能避免的异常,尽量在事先做判断来避免异常的发生,当判断时发现逻辑上已经不能往下走了,需要停止流程,这时候将异常抛出并准确的提示使用者问题所在。
对于事先无法预判的异常需要对其进行处理。
异常分运行时异常 RuntimeException 和 检查异常Checked Exception,运行时异常一般用在由于接口方法使用不当的时候
如: 使用了null获取属性方法, 数组下标越界,除法运算除以0等
- 如果你调用服务方法的方式不正确,你应该马上修改代码,避免发生RuntimeException
- 如果是用户方法调用你的方法的方式不正确,你应该立刻抛出RuntimeException,强制让使用者修正代码或改变使用方式,防止问题蔓延
- 一般情况下,不要捕获或声明RuntimeException,需要做的是完善程序代码。因为问题在于你的程序本身有问题,如果你用异常流程处理了,反而让正常流程问题一直存在
对于检查异常,一般先看能不能处理,能处理的异常使用try-catch 语句块捕获处理,不能处理使用throws 分类型抛出给上一级处理
使用try-catch语句块处理时一般需要注意以下几方面
- try语句块内要分清稳定代码和非稳定代码,对于稳定的不会出现异常的代码不要放到try语句块中
- catch捕获的异常一定要处理
- 若使用了finally 语句块,在语句块内一定要对资源对象,流对象进行关闭(jdk1.7之后 可以使用try-with-resources替代)
- finally中不要使用return语句,因为finally语句块最后一定会执行,这里的return语句会覆盖之前的return语句
参考:
[1] 有效处理javay异常的三个原则
[2] 阿里巴巴Java开发手册
Java异常处理原则与技巧总结的更多相关文章
- JAVA异常处理原则和log4j输出详细异常分析
1.多用try,catch;不要一个try,catch包含所有内容 好处:不同模块抓取不同异常,某一模块异常挂了,不影响其他模块的程序的进行 2.多写几个catche:尽量不要使用Exception这 ...
- java异常处理机制 (转载)
java异常处理机制 本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C ...
- Java—异常处理总结
异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地方出 ...
- 基础知识《十一》Java异常处理总结
Java异常处理总结 异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制 ...
- Java异常处理总结Exception\Error
Java异常处理总结Exception\Error 2012-12-28 08:17:17| 分类: JAVA | 标签:java |举报|字号 订阅 Java异常处理总结 ...
- Java异常处理和设计
在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻 ...
- Java提高篇——Java 异常处理
异常的概念 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error:如果你用Syst ...
- java异常处理的设计
有一句这样话:一个衡量Java设计师水平和开发团队纪律性的好方法就是读读他们应用程序里的异常处理代码. 本文主要讨论开发Java程序时,如何设计异常处理的代码,如何时抛异常,捕获到了怎么处理,而不是讲 ...
- Java程序性能优化技巧
Java程序性能优化技巧 多线程.集合.网络编程.内存优化.缓冲..spring.设计模式.软件工程.编程思想 1.生成对象时,合理分配空间和大小new ArrayList(100); 2.优化for ...
随机推荐
- 2018-8-10-win10-uwp-如何打包Nuget给其他人
title author date CreateTime categories win10 uwp 如何打包Nuget给其他人 lindexi 2018-08-10 19:16:50 +0800 20 ...
- angular ui 路由传参
1. ui-sref.$state.go 的区别 ui-sref 一般使用在 <a>...</a>: $state.go('someState')一般使用在 controlle ...
- js数组冒泡排序
文章地址 https://www.cnblogs.com/sandraryan/ js数组的冒泡排序是最经典的一种排序方式(我以为). 冒泡排序是吧一组数组的元素两两比较,交换位置,通过多轮比较,实现 ...
- Python--day67--内容回顾
- HDU 2602Bone Collector 01背包问题
题意:给出一个t代表有t组数据,然后给出n,n代表有n种石头,v代表旅行者的背包容量,然后给出n种石头的价值和容量大小,求能带走的最大价值 思路:01背包问题,每种石头只有拿与不拿两种状态.(其实我是 ...
- gSOAP calc服务端与客户端示例
1. Web服务定义描述头文件 typedef double xsd__double; int ns__add(xsd__double a, xsd__double b, xsd__double &a ...
- win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序
本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...
- ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(15)之前台网站页面
源码下载地址:http://www.yealuo.com/Sccnn/Detail?KeyValue=c891ffae-7441-4afb-9a75-c5fe000e3d1c 本项目主要是一个素材的分 ...
- H3C生成树协议
- html根据下拉框选中的值修改背景颜色
错误的写法 <!doctype html><html><head><meta charset="utf-8"><title&g ...