异常的处理

一、异常

  • 发现错误的理想阶段是在编译期间,如果不行,则只能在运行期间处理
  • 容器,泛型,js中引入的ts,都是将运行期错误提前到编译期
  • 如果当前自己能处理,那就处理
  • 如果自己处理不了,就看看别人能不能处理, 把这个问题抛出来,交给更高一层去处理

1. 基本异常

# 异常发生时
1. 系统使用new,在堆上创建出一个异常对象
2. 当前程序的执行路径被终止,并且在当前环境弹出对异常对象的引用
3. 异常处理机制接管程序,寻找一个合适的地方来继续执行程序
4. 要么换一种方式来执行,要么继续执行下去

# 异常参数
1. throw关键字: 可以理解为一个异常对象的this引用
2. 类比于方法的一种返回值
3. 错误信息可以用异常的 类名 或者 异常信息来表示

# 异常处理模式
1. 终止模型
2. 恢复模型

2. 自定义异常

  • 选择意思相近的异常来继承
  • 自定义异常的名字非常关键: 见名知意

3. 异常说明

  • library为方法提供异常说明,说明该方法可能发生的异常
  • 强制客户端程序在代码中去处理这个异常
  • 通过throws关键字在方法声明后面实现
  • 被检查的异常
- 自定义的受检查异常: 必须是Exception的子类,或者非 RuntimeException 的子类
- 声明: 
     1.1 要么在方法声明处单独抛出,
     1.2 要么在try 模块抛出同时必须要求在方法声明处抛出
     1.3 调用方就要强制去处理
package com.erick;

public class Demo04 {
    public static void main(String[] args) {

    }

    private static void method02() {
        /*编译器就回强制要求: 要么继续抛出该异常,要么使用try catch来处理该异常*/
        method01();
    }

    /*1.  自定义的受检查异常: 必须是Exception的子类,并且不是 RuntimeException*/
    private static void method01() throws ErickException {
        System.out.println("hello,exception");
    }
}


class ErickException extends Exception {
    public ErickException() {

    }

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

4. 异常信息

  • 基本信息
package com.erick;

public class Demo05 {
    public static void main(String[] args) {
        try {
            int num = 1 / 0;
        } catch (Exception e) {
            System.out.println(e.getClass());       // class java.lang.ArithmeticException
            System.out.println(e.getClass().getName()); //java.lang.ArithmeticException
            System.out.println(e.getClass().getSimpleName()); //ArithmeticException

            System.out.println(e.getMessage());     // by zero
            System.out.println(e.getCause());       // null
        }
    }
}
  • 栈轨迹
package com.erick;

public class Demo05 {
    public static void main(String[] args) {
        try {
            second();
        } catch (Exception e) {
             // com.erick.Demo05.first(Demo05.java:20)
             // com.erick.Demo05.second(Demo05.java:16)
             // com.erick.Demo05.main(Demo05.java:6)

            /*获取到栈调用的轨迹*/
            StackTraceElement[] stackTrace = e.getStackTrace();
            for (StackTraceElement element : stackTrace) {
                System.out.println(element);
            }

            /*java.lang.ArithmeticException: / by zero
            at com.erick.Demo05.first(Demo05.java:26)
            at com.erick.Demo05.second(Demo05.java:22)
            at com.erick.Demo05.main(Demo05.java:6)*/

            // 栈调用的轨迹,异常逻辑
            e.printStackTrace();
        }
    }

    private static void second() {
        first();
    }

    private static void first() {
        int num = 1 / 0;
    }
}

5. 异常链

  • 捕获原来的异常,并抛出新的异常,就会把原来的异常信息丢失
  • Error, Exception, RuntimeException这三个类: 可以传递cause来保存原来异常信息
  • 其他类需要用initCause来保存
package com.erick;

public class Demo05 {
    public static void main(String[] args) {
        third02();
    }

    private static void third01() {
        try {
            second();
        } catch (Exception e) {
            /*1. 捕获原来的异常,并抛出新的异常,就会把原来的异常信息丢失*/

 /*           Exception in thread "main" java.lang.RuntimeException: ErickException
            at com.erick.Demo05.third(Demo05.java:12)
            at com.erick.Demo05.main(Demo05.java:5)
            */
            throw new RuntimeException("ErickException");
        }
    }

    private static void third02() {
        try {
            second();
        } catch (Exception e) {
            // 1. 捕获的异常不是  Error Exception RuntimeException
            // 必须使用新异常的initCause
            RuntimeException erickException = new RuntimeException("ErickException");
            erickException.initCause(e);
            throw erickException;
        }
    }

    private static void second() {
        first();
    }

    private static void first() {
        int num = 1 / 0;
    }
}
package com.erick;

public class Demo06 {
    public static void main(String[] args) {
        method01();
    }

    private static void method01() {
        try {
            method002();
        } catch (Exception e) {
            // 捕获的异常属于三个基本异常中的,因此可以用cause的方式来传递异常链
            throw new RuntimeException("ErickException", e);
        }
    }

    private static void method002() {
        method003();
    }

    private static void method003() {
        throw new RuntimeException("HAHAHAHA");
    }
}

6. 方法覆盖

  • 方法覆盖时候,只能抛出在基类方法的异常声明里面列出的异常类型

7. 其他

  • 只有在你知道如何处理的时候,才去捕获异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值