java异常设计_java异常设计

异常的分类结构图

4827bd67f6a6e3174741185c17232cdb.png异常机制是为了解决什么问题?

它也是线程结束的一种方式,从某中角度来讲,它与正常return没有什么区别,只不过是一种异常的方式结束。那为什么需要这种异常的机制呢?异常机制本身也是划分了严重程度,如:Error/Exception. 它以一种不侵入正常流程编码的形式,尽量不让程序崩溃(Error类型的异常), 同时给开发者友好的提示信息(方便问题的定位)。各种异常在什么场景下出现?能否处理?

Error错误

这种异常通常都是程序级别的错误,直接会引起程序崩溃。

常见的异常有:VirtualMachineError(jvm错误)、AWTError、OutOfMemoryError(堆内存溢出)、StackOverflowError(栈内存溢出)、NoClassDefFoundError、NoSuchMethodError。

这种错误通常程序本身无法处理,需要对JVM优化处理,如:参数大小设置、引入依赖包等。

RuntimeException运行时异常

这种异常通常都是在程序运行的过程中出现的异常。要么是BUG,要么是参数错误,而这一切的异常情况在编码的时候根本无法预料。会让单个方法的调用直接异常结束.

常见的异常有:IllegalArgumentException(不合法参数异常)、IllegalAccessException(不合法的访问)、ClassCastException(类型转换异常)、IndexOutOfBoundsException(边界异常)、NumberFormatException(数字格式异常).

运行时异常通常有传入的参数错误或程序BUG引起,这种异常需要用户或开发者根据提示信息来修改问题。

CheckedException检查型异常

非运行时异常,是在编码时显示定义的异常,这种异常必须捕获(try catch)或抛出(throws),否则编译时无法通过。

常见的异常有:IOException(IO异常,如:SocketException网络异常,文件流异常)、SQLException(sql异常).

检查型异常,通常都是可预见的异常情况,而在编码的时候进行的一种补救措施。根据什么来设计异常?

根据异常类型来设计

Error错误类型的异常,通常都属于系统级别的问题. 除非我们要去终止整个进程,否则我们一般都不会涉及到此类的异常设计;

CheckedException可检查型异常,属于应用编码级别的问题.它属于一种备用手段,比如:SocketException/FileException,捕获之后,还可以进一步的补救.我认为它属于一个另类的编程思想.

RuntimeException运行时异常,属于请求级别/一次方法调用的问题. 在程序处理的时候,总会有想不周全的问题.比如:用户传入的参数不正确;开发者的BUG;这种问题通常都会中止此次请求或方法调用,返回错误提示信息,然后再由对应的人员去解决.

根据谁造成的问题谁来解决的原则

引起异常问题的原因无非两种:客户和开发者.

当我们的应用内存不够或磁盘空间不足或系统宕机,这种出现系统级别的错误. 只能由运维或开发者来解决,对于客户来说并不可见,也并不关心.

当我们的应用某个方法中的片段代码,因为开发者的疏忽,而非造成的BUG.这种问题只能由开发者来解决,对于客户来说并不可见,也不关心.

当客户调用某个方法时,传入的参数不正确或数据不正确,这种问题只能由客户来解决,而开发者只需要友好的提示给客户.

异常的设计样例/**

* 程序BUG出现的异常.用于开发者定位问题所在.

* @author yangyc

*/

public class AppException extends RuntimeException{

public AppException(String message, Throwable cause) {

super(message, cause);

}

}

/**

* 提示性异常.由调用者来解决.如果参数为空,参数格式不正确,数据获取不到等.

* @author yangyc

*/

public class PromptException extends RuntimeException {

public PromptException(String message, Throwable cause) {

super(message, cause);

}

}

/**

* 远程调用服务的异常.这种在编码期就可以预料到的问题.

* @author yangyc

*/

public class RpcException extends Exception {

public RpcException(String message, Throwable cause) {

super(message, cause);

}

}

使用异常技巧

1.什么时候使用检查型异常或运行时异常?

异常可预见或可补救的情况,采用检查型异常,从编码的角度增强程序的健壮性. 相反无法预料, 问题出现就必须中止的问题,采用运行时异常.

2.异常什么时候捕获?

通常在调用起点捕获或AOP的更上层统一处理,中间不要去捕获; 明确知道问题并可以对此类异常处理,则捕获,而这种类型的异常,通常都会进行异常转换,继续往上层抛出.

3.异常捕获时,try catch的内容应该是多少?

一般不宜将捕获的代码太长,会影响异常处理机制的复杂度;同时,也应考虑将紧密代码放在一起,保证代码的可读性.

4.异常的转换

有些时候,捕获异常之后,会抛出一个新异常,继续由后续程序处理.这时,就需要进行异常的转换.比如:将检查型异常转换成运行时异常.

5.异常的传递

当出现异常转换时,要注意原始异常信息不丢失.应该使用 new XxxException(msg, e)这个方法.

6.尽早抛出异常,尽晚的捕获异常,明确的抛出异常类型

7.捕获异常后,不要忽略异常public void doNotIgnoreExceptions() {

try {

// do something

} catch (NumberFormatException e) {

// this will never happen

}

}

8.不要捕获Throwable

Throwable是所有异常(Exception)和错误(Error)的父类,虽然它能在catch从句中使用,但永远都不要这样做!如果你在catch从句中使用了Throwable,它将不仅捕获所有异常,它还将捕获所有错误,错误是由JVM抛出的,用来表明不打算让应用来处理的严重错误。OutOfMemoryError和StackOverflowError便是典型的例子,它们都是由于一些超出应用处理范围的情况导致的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值