如何规范的使用Java异常

本文参照《重构》、《Effective Java》及一些论坛博文进行总理及总结,如有不对的地方,欢迎大家指正、交流学习!

写了几年代码,对于异常这个概念既熟悉又陌生,看了很多同事写的代码也都是各有各的风格,对于实际项目当中的非正常流程是应该返回错误代码还是抛出异常?抛出什么样的异常?从来没有认真的思考和总结过。本文参照一些技术书籍及博客论坛对该如何规范的使用异常的使用进行了总结。

一、异常模型

这里写图片描述


1、运行时异常(非检查异常)

在Java中RuntimeException及其派生类都属于运行时异常(非检查异常),运行时异常可以不在函数声明中添加throws语句,调用函数也不需要进行强制处理,如果有异常产生也可以不使用try…catch进行处理,异常则将由JVM进行处理。

虽然运行时异常可以不使用try…catch进行处理,但是如果一旦发生异常,则肯定会导致程序中断执行,所以,为了保证程序出错后依然可以执行,在开发时最好使用try…catch的异常处理机制进行处理。

常见的运行时异常有: NullPointerException、IndexOutOfBoundsException、ClassCastException。

2、非运行时异常(检查异常)

在Java中所有不是RuntimeException派生的Exception异常都属于非运行时异常(检查异常),当函数中存在非运行时异常的操作时,函数声明中必须包含throws语句。调用函数也必须对该异常进行处理,如果不进行处理则必须在调用函数上声明throws语句。非运行时异常是Java首创的,在编译期对异常的处理有强制性要求。

常见的非运行时异常有:IOException、SQLException。

二、异常的应用

1、以异常取代错误代码

在实际的项目开发中,我们在调用第三方的业务接口时经常碰到这样的情况:返回值通常是一个int类型或json字符串,通过不同的数字代码代表不同的错误含义。如下:

private int account;   //账户总额

/**
 * @param amount : 取款金额
 * @return -1:账户余额不足  0:取款成功
 */
public int takeMoney(int amount){
    if(account < amount) {
        return -1;
    }else{
        account = account - amount;
    }
    return 0;
}

函数抛不抛异常与函数本身的语义密切相关,如果函数正常返回说明函数完成了既定的语义,上述代码无论能否顺利完成取款操作都会正常返回,而调用者只能通过返回码来判断是否正常执行。代码的可理解性应该是我们虔诚追求的目标,《重构:改善既有代码的设计》一书中指出:Replace Error Code with Exception(以异常取代错误代码)。我们应将上述逻辑替换为如下这样的代码:

private int account;   //账户总额

/**
 * @param amount 取款金额
 */
public void  takeMoney(int amount){
    if(account < amount) {
        throw new IllegalArgumentException("账户余额不足");   
    }
    account = account - amount;
}

2、运行时异常及非运行时异常的应用

在实际开发中,使用运行时异常还是非运行时异常关键在于:非正常的分支流程应该是由方法调用者检查还是方法本身检查。

如果检查非正常流程分支是调用者的责任,那么出现非正常流程分支时则是一个编程错误,所以应该抛出运行时异常(非检查异常)。如下取款示例代码,如果调用者在调用takeMoney()函数之前没有进行余额检查,如果传入的取款金额大于账户总额,此时则是一个编程错误,所以抛出运行时异常(非检查异常)。

/**
 * 取款业务类
 */

public class BankService{
    private int account;   //账户总额
    /**
     * @param amount 取款金额
     */
    public void  takeMoney(int amount)  {
        if(account < amount) throw new IllegalArgumentException("账户余额不足");  //抛出运行时异常
        account -= amount;
    }
}

如果检查非正常流分支是函数本身的责任,那么我们则必须在方法中声明可能会抛出这种异常,那么也就提醒了调用者注意这个异常并采取相应的处理措施,如下代码所示,

/**
 * 自定义异常,继承自Exception类
 */
public class BalanceException extends Exception {
    public BalanceException(){
        super();
    }

    public BalanceException(String message){
        super(message);
    }
}

/**
 * 取款业务类
 */
public class BankService{
    private int account;   //账户总额
    /**
     * @param amount 取款金额
     */
    public void  takeMoney(int amount) throws BalanceException {
        if(account < amount) throw new BalanceException();
        account -= amount;
    }
}

《Effecvive java》Java异常使用规范

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值