Java异常处理最佳实践

总结一些Java异常的处理原则

Java异常处理最佳实践

不要忘记关闭资源

在finally里关闭资源

public void readFile() {
    FileInputStream fileInputStream = null;
    File file = new File("./test.txt");
    try {
        fileInputStream = new FileInputStream(file);
        int length;
        byte[] bytes = new byte[1024];
        while ((length = fileInputStream.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, length));
        }
    } catch (FileNotFoundException e) {
        logger.error("找不到文件", e);
    } catch (IOException e) {
        logger.error("读取文件失败", e);
    } finally {
        if (fileInputStream != null) {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                logger.error("关闭流失败", e);
            }
        }
    }
}

用try-with-resource关闭资源

public void readFile2() {
    File file = new File("./test.txt");
    try(FileInputStream fileInputStream = new FileInputStream(file)) {
        int length;
        byte[] bytes = new byte[1024];
        while ((length = fileInputStream.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, length));
        }
    } catch (FileNotFoundException e) {
        logger.error("找不到文件", e);
    } catch (IOException e) {
        logger.error("读取文件失败", e);
    }
}

使用描述性消息抛出异常

指定具体的异常

  • 用NumberFormatExcepton而不是Exception,这样能更快的定位问题
  • NumberFormatException 是运行时异常
public void numberFormat() {
    try {
        String year = "2018";
        System.out.println(Integer.parseInt(year));
    } catch (NumberFormatException e) { // 捕获NumberFormatExceptoin而不是Exception
        logger.error("年份格式化失败", e); // 描述一下异常
    }
}

给异常加注释

// 自定义一个异常
class NotFoundGirlFriendException extends Exception {
    public NotFoundGirlFriendException(String message) {
        super(message);
    }
}

/**
 *
 * @param input
 * @throws NotFoundGirlFriendException input为空抛出异常
 */
public void doSomething(String input) throws NotFoundGirlFriendException {
    if (input == null) {
        throw new NotFoundGirlFriendException("出错了");
    }
}

优先捕获具体异常

public int getYear(String year) {
    int retYear = -1;
    try {
        retYear = Integer.parseInt(year);
    } catch (NumberFormatException e) {
        logger.error("年份格式化失败", e);
    } catch (IllegalArgumentException e) {
        logger.error("非法参数", e);
    }
    return retYear;
}

不要捕获Throwable

  • Throwable是所有异常和错误的父类,会把error捕获
  • error是那些无法恢复的jvm错误,eg:StackOverflowError和OutOfMemoryError
public void test6() {
    try {
    } catch (Throwable e) {
    }
}

不要忽略异常

public void test7() {
    try {

    } catch (NumberFormatException e) {
        logger.error("即便你认为不可能走到这个异常,也要记录一下", e);
    }
}

捕获和抛出只选择一种

  • 不要同时记录并抛出异常,会导致相同错误日志输出多次
public void foo() {
    try {
        new Long("xyz");
    } catch (NumberFormatException e) {
        logger.error("字符串格式化成Long失败", e);
        throw e;
    }
}

包装异常不要丢弃原始异常

class MyBusinessException extends Exception {
    public MyBusinessException(String message) {
        super(message);
    }
    public MyBusinessException(String message, Throwable cause) {
        super(message, cause);
    }
}

public void wrapException(String id) throws MyBusinessException {
    try {
        System.out.println(Long.parseLong(id));
    } catch(NumberFormatException e) {
        throw new MyBusinessException("ID格式化失败", e);
    }
}

参考

Java 异常处理最佳实践(2018)

猜你喜欢

转载自www.cnblogs.com/okokabcd/p/9694598.html