zoukankan      html  css  js  c++  java
  • 异常总结

    一、官方API对此的解释: 

    1、Throwable:异常和错误的基类,提供了错误堆栈实现等一系列方法。 两个直接子类: Error & Exception

    2、两个子类区别:

         Error: 程序不应该捕捉的错误,应该交由JVM来处理。一般可能指非常重大的错误。

         Exception:程序中应该要捕获的错误。

         RuntimeException:运行期异常,是Exception的子类,但勿需捕捉的异常超类

    二、各自代码中的表象  

    Error & RuntimeException:不需要异常处理的,即无try/catch or throws的,编译器认可此种方式;

    Exception(排除RuntimeException):编译器强制要求做异常处理的,即必须要 try/catch or throws的;

    进一步解释: Exception分为checked Exception & unchecked Exception两种,

                      unchecked Exception指勿须检查的异常,也即RuntimeException/Error,运行期错误JVM来打理;

                      checked Exception指必须处理的异常,否则编译器就不让过;

    三、为何这样设计?    

    如上述,Throwable存在2种维度的设计: 1、是否checked  2、 异常级别

    是否checked: 表象很明显,编译器会强制检测;

    异常级别: 分为 错误和异常,可这个如何来区分呢?我确实很困惑,应该是个人理解的把握了。

    四、异常常用关键点知识

    1、保留异常源头

        异常处理是层级追溯机制,因此异常可被多次抛出,但只要不改变源异常的句柄及其stackTrace,就可一直保留异常源头。

        也即简单的throw e(最初的那个异常),异常源头依旧被保留。

    2、改变异常源头

        如果想改变异常源头,通过抛出一个新异常或在层级机制处理中改变其stackTrace即可。

        如在调用方法中e.fillStackTrace() or throw new Excepiton("...")即可定位当前方法为异常源头。

    3、自定义异常

         一般来说,自定义异常多以checked的为主,也即从Exception继承,实现非常简单,复杂度就看业务需要了,就不多说了。

    4、附上部分代码,参照Thinking in java中的实现 

    复制代码
    public class ThrowableExceptionStudy {    
        // 异常测试
        public static void main(String[] args) throws InterruptedException {        
            reThrowTest();  // 异常重新抛出测试(可控制改变源头)
            rethrowNew();  // 抛出一个新异常测试(改变源头)
            runtimeExceptionTest(); // 运行期异常测试
            errorTest();  // error测试
        }
        
        /**
         * 异常重新抛出测试
         */
        private static void reThrowTest() {
            try {
                g();
            } catch (Exception e) { // 抛出Exception
                System.out.println("Caught exception in reThrowTest, e.printStackTrace()");
                e.printStackTrace();
            } catch    (Throwable t) { // 抛出Throwable
                System.out.println("Caught throwable in reThrowTest, t.printStackTrace()");
                t.printStackTrace();
            }
        }
    
        /**
         * 异常源头
         */
        private static void f() throws Exception {
            System.out.println("originating the exception in f()");
            throw new Exception("thrown from f()");
        }
    
        /**
         * 异常重新抛出,不改变异常句柄
         * 以两种方式抛出:1、不改变异常源头 2、改变异常源头
         */
        private static void g() throws Throwable {
            try {
                f();
            } catch (Exception e) {
                System.out.println("Inside g(), e.printStackTrace()");
                e.printStackTrace();
                //throw e; // a: 不改变异常源头
                throw e.fillInStackTrace(); // b:改变异常源头, 通过fillInStatckTrace实现
            }
        }
        
        /**
         * 抛出一个新的异常,改变了异常句柄
         */
        private static void rethrowNew() {
            try {
                f();
            } catch (Exception e) {
                System.out.println("Caught in rethrowNew, e.printStackTrace()");
                e.printStackTrace();
                //throw new NullPointerException("from rethrowNew"); // RuntimeException,编译器自动处理
                try {
                    throw new Exception("from rethrowNew"); // 非RuntimeException,必须捕捉
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
    
        /**
         * 运行期异常,勿须捕捉,编译器会自动处理
         */
        private static void f1() {
            throw new RuntimeException("From f1()");
        }
    
        /**
         * 运行期异常测试
         */
        private static void runtimeExceptionTest() {
            try{
                f1();
            } catch (RuntimeException e){
                e.printStackTrace();
            }
        }
        
        /**
         * Error错误
         */
        private static void error() {
            throw new Error("custome error,not exception. ");
        }
        
        /**
         * Error测试
         */
        private static void errorTest(){
            try{
                error();
            } catch (Error t){ 
                t.printStackTrace();
            }
        }
    }
    复制代码

    运行结果:

    复制代码
    originating the exception in f()
    Inside g(), e.printStackTrace()
    java.lang.Exception: thrown from f()
        at com.chq.study.ThrowableExceptionStudy.f(ThrowableExceptionStudy.java:40)
        at com.chq.study.ThrowableExceptionStudy.g(ThrowableExceptionStudy.java:49)
        at com.chq.study.ThrowableExceptionStudy.reThrowTest(ThrowableExceptionStudy.java:25)
        at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:14)
    Caught exception in reThrowTest, e.printStackTrace()
    java.lang.Exception: thrown from f()
        at com.chq.study.ThrowableExceptionStudy.g(ThrowableExceptionStudy.java:54)
        at com.chq.study.ThrowableExceptionStudy.reThrowTest(ThrowableExceptionStudy.java:25)
        at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:14)
    originating the exception in f()
    Caught in rethrowNew, e.printStackTrace()
    java.lang.Exception: thrown from f()
        at com.chq.study.ThrowableExceptionStudy.f(ThrowableExceptionStudy.java:40)
        at com.chq.study.ThrowableExceptionStudy.rethrowNew(ThrowableExceptionStudy.java:63)
        at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:15)
    java.lang.Exception: from rethrowNew
        at com.chq.study.ThrowableExceptionStudy.rethrowNew(ThrowableExceptionStudy.java:69)
        at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:15)
    java.lang.RuntimeException: From f1()
        at com.chq.study.ThrowableExceptionStudy.f1(ThrowableExceptionStudy.java:80)
        at com.chq.study.ThrowableExceptionStudy.runtimeExceptionTest(ThrowableExceptionStudy.java:88)
        at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:16)
    java.lang.Error: custome error,not exception. 
        at com.chq.study.ThrowableExceptionStudy.error(ThrowableExceptionStudy.java:98)
        at com.chq.study.ThrowableExceptionStudy.errorTest(ThrowableExceptionStudy.java:106)
        at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:17)
  • 相关阅读:
    【CITE】当类库项目中无法使用Application.StartupPath的时侯 (注:主要是在进行反射读取文件的时候!!)
    设置pictureBox的边框颜色
    怎么在Form1调用Form2中的成员?
    【CITE】DrawImage方法详解(转)
    Python-正则表达式实现计算器功能
    Python-面向对象进阶
    Python基础-封装与扩展、静态方法和类方法
    Python基础-接口与归一化设计、抽象类、继承顺序、子类调用父类,多态与多态性
    Python基础-继承与派生
    Python基础-月考
  • 原文地址:https://www.cnblogs.com/ruixinyu/p/5549733.html
Copyright © 2011-2022 走看看