说说Java中的异常处理

107 阅读2分钟

一.处理异常的几种方式

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();
        }
    }
}