Java异常处理原则与技巧总结
⼀处理原则
Java异常代码中我们使⽤异常的⽬的是让异常的异常类型来提⽰“什么”被抛出了--- 即出了什么问题;⽤异常的栈打印信息来跟踪异常
在“哪⾥”抛出 --- 即哪⾥出了问题;
异常提⽰信息来提⽰“为什么”会抛出 --- 即出问题的原因。在对异常进⾏处理时,遵循以下原则可以有助于在调试过程中最⼤限度的使⽤好异常。
1. 具体明确
2. 提早抛出
3. 延迟捕获
1.具体明确
具体明确指的是在抛出异常时需要针对具体问题来抛出异常,抛出的异常要⾜够具体详细;在捕获异常
时需要对捕获的异常进⾏细分,这时会有多个catch语句块,这⼏个catch块中间泛化程度越低的异常需要越放在
前⾯捕获,泛化程度⾼的异常捕获放在后⾯,这样的好处是如果出现异常可以近可能得明确异常的具体类型是什么。
例如 FileInputStream 的⼀个构造⽅法如下, 对file对象做检查后判断file是否有效,如果⽆效直接抛出FileNotFoundException,⽽不是IOException或者其他更宽泛的Exception
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? Path() : null);
SecurityManager security = SecurityManager();
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的使用方法 对于检查异常,⼀般先看能不能处理,能处理的异常使⽤try-catch 语句块捕获处理,不能处理使⽤throws 分类型抛出给上⼀级处理
使⽤try-catch语句块处理时⼀般需要注意以下⼏⽅⾯
1. try语句块内要分清稳定代码和⾮稳定代码,对于稳定的不会出现异常的代码不要放到try语句块中
2. catch捕获的异常⼀定要处理
3. 若使⽤了finally 语句块,在语句块内⼀定要对资源对象,流对象进⾏关闭(jdk1.7之后可以使⽤try-with-resources替代)
4. finally中不要使⽤return语句,因为finally语句块最后⼀定会执⾏,这⾥的return语句会覆盖之前的return语句
参考:
[1]
[2] 阿⾥巴巴Java开发⼿册
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论