首页 > 编程语言 > 详细

java异常设计

时间:2018-07-25 16:02:08      阅读:212      评论:0      收藏:0      [点我收藏+]
  • 异常的分类结构图

  • 技术分享图片

    • 异常机制是为了解决什么问题?

    它也是线程结束的一种方式,从某中角度来讲,它与正常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便是典型的例子,它们都是由于一些超出应用处理范围的情况导致的。


    https://www.cnblogs.com/beatIteWeNerverGiveUp/p/5915255.html


    java异常设计

    原文:http://blog.51cto.com/881206524/2150012

    (0)
    (0)
       
    举报
    评论 一句话评论(0
    关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
    © 2014 bubuko.com 版权所有
    打开技术之扣,分享程序人生!