一.处理异常的几种方式
1.首先理解为什么需要异常处理?
因为程序运行时有各种异常情况出现,我们不能只考虑正常执行流程 必须考虑异常情况出现的时候 程序执行链路
处理了异常意味着程序可以继续向下执行 如果抛出异常则执行的线程终止
2.异常的分类
3.几种处理异常的方式
1)方法声明中抛出异常 throws exception
2)方法执行体中抛出异常 throw new RunimeException
3)使用try catch捕获异常 在catch语句块中处理异常
二.finally的使用
1.try catch finally语句块 我们正常是想要无论是否发生异常 都让finally得到执行
2.不要在 finally 语句块中使用 return! 当 try 语句和 finally 语句中都有 return 语句时,try 语句块中的 return 语句会被忽略。这是因为 try 语句中的 return 返回值会先被暂存在一个本地变量中,当执行到 finally 语句中的 return 之后,这个本地变量的值就变为了 finally 语句中的 return 返回值
public static void main(String[] args) {
System.out.println(f(2));
}
public static int f(int value) {
try {
return value * value;
} finally {
if (value == 2) {
return 0;
}
}
}
结果为0 这就说明finally中的return会替换try中的return
3.finally中的代码一定会被执行吗?
不一定 当虚拟机提前关闭的时候 finally中代码不会得到执行
三.在实际业务场景中如何处理异常更为合适?
个人经验来看:
1.在核心业务处理的逻辑中是必须要用try catch来处理异常的
2.在catch中 用log记录下来异常信息
正确的写法是: log.error("xxxx error:",e); 注意不要用log.error("xxx error:"+e)
因为后者只会打印出e.getMessage 并不会打印出e的堆栈信息 就很难去排查问题 可以说几乎这个异常处理是没什么作用的
3.如果用到了必须关闭的资源 例如流
可以用try with resource简化
也可以用lombok的@Cleanup注解简化代码:
public class TestResource {
public static void main(String[] args) {
readByTryWithResource();
readByAnnotation();
}
private static void readByTryWithResource() {
try (InputStream in = Files.newInputStream(Paths.get("D:\files\test.txt"))){
int read = in.read(new byte[10], 0, 3);
System.out.println("read = " + read);
}catch (Exception e){
e.printStackTrace();
}
}
private static void readByAnnotation() {
try {
@Cleanup InputStream in = Files.newInputStream(Paths.get("D:\files\test.txt"));
int read = in.read(new byte[10], 0, 3);
System.out.println("read = " + read);
}catch (Exception e){
e.printStackTrace();
}
}
}