异常及其处理

目录

1.体系结构

编译时异常和运行时异常的区别

JVM默认处理异常的方式

2.异常处理的方式 

2.1自己不处理,交给调用者处理

(1)    throws 方式处理异常

(2)        throw抛出异常

​ 2.2    自己处理的方式

    (1)try-catch方式处理异常

Throwable成员方法

自定义异常 


1.体系结构

 error:错误,因硬件问题无法解决的。

Exception:异常类,可以进行处理的

                RuntimeException及其子类:称运行时异常,程序运行时发生的报错

                除了 “RuntimeException及其子类”之外的异常:称编译时异常,必须先处理,否则程序不能编译运行。显示红色波浪线

 

编译时异常和运行时异常的区别

  • 编译时异常

    • 都是Exception类及其子类

    • 必须显示(主动)处理,否则程序就会发生错误,无法通过编译,显示红色波浪线无法进行编译

  • 运行时异常

    • 都是RuntimeException类及其子类

    • 无需显示处理,也可以和编译时异常一样处理

 //思考:控制台为什么会有这样的红色字体呢? 是谁打印的?
        int [] arr = {1,2,3,4,5};
        System.out.println(arr[10]);//当代码出现了异常,那么就在这里创建了一个异常对象.
                                    //new ArrayIndexOutOfBoundsException();
                                    //首先会看,程序中有没有自己处理异常的代码.
                                    //如果没有,交给本方法的调用者处理.
                                    //最终这个异常会交给虚拟机默认处理.
                                    //JVM默认处理异常做了哪几件事情:
                                    //1,将异常信息以红色字体展示在控制台上.
                                    //2,停止程序运行. --- 哪里出现了异常,那么程序就在哪里停止,下面的代码不执行了.
        System.out.println("嘿嘿嘿,我最帅");//此输出语句不在执行

JVM默认处理异常的方式

  • 如果程序出现了问题,我们没有做任何处理,最终JVM 会做默认的处理,处理方式有如下两个步骤:

    • 把异常的名称,错误原因及异常出现的位置等信息输出在了控制台

    • 程序停止执行

2.异常处理的方式 

2.1自己不处理,交给调用者处理

(1)    throws 方式处理异常

定义格式

public void 方法() throws 异常类名 {
    
}

注意:这个格式是写在方法的定义处,标识声明一个异常。【主动标明一个异常】 

 无论编译时异常还是运行时异常,如果方法的调用者未对其处理,最终交给虚拟机JVM处理报错。程序停下来,后面的代码不再执行

注意事项

  • 这个throws格式是跟在方法的括号后面的

  • 编译时异常必须要进行处理,两种处理方案:try...catch …或者 throws。如果采用 throws 这种方案,在方法上进行显示声明,将来谁调用这个方法谁处理,如果都没处理就交给JVM处理,进行报错

  • 运行时异常因为在运行时才会发生,所以在方法后面可以不写,运行时出现异常默认交给jvm处理


(2)        throw抛出异常

思考∶
以前出现了异常,虚拟机帮我们创建一个异常对象,抛给调用者。但是如果我们需要自己手动创建一个异常对象该如何写?

  • 格式

    throw new 异常();

    或:

    throw new xxxException("异常产生的原因");
    注意:
        1.throw关键字必须写在方法的内部
        2.throw关键字【后边】【new的对象】【必须是】Exception或者Exception的子类对象
        3.throw关键字抛出指定的异常对象,我们就必须处理这个异常对象
            throw关键字后边创建的是【RuntimeException】或者是【 RuntimeException】的【子类对象】,我们可以不处理,默认交给JVM处理(打印异常对象,中断程序)
            throw关键字后边创建的是【编译异常】(写代码的时候报错),【程序根本无法进行编译运行】我们就必须处理这个异常,要么【throws】,要么【try...catch】
    
            

     

  • 注意

    这个格式是在方法内的,表示当前代码手动抛出一个异常,下面的代码不用再执行了

      public static void main(String[] args) {
            System.out.println("家里有一个貌美如花的老婆");
            System.out.println("还有一个当官的兄弟");
            System.out.println("自己还有一个买卖");
            System.out.println("这样的生活你要不要?");
            throw new RuntimeException(); //当代码执行到这里,就创建一个异常对象
                                        //该异常创建之后,暂时没有手动处理.抛给了调用者处理
                                        //下面的代码不会再执行了.
            //System.out.println("武大郎的标准生活");
        }
  • throws和throw的区别

    throwsthrow
    用在方法声明后面,跟的是异常类名用在方法体内,跟的是异常对象名
    表示声明异常,调用该方法有可能会出现这样的异常表示手动抛出异常对象,由方法体内的语句处理
public class ExceptionDemo8 {
    public static void main(String[] args) {
        //int [] arr = {1,2,3,4,5};
        int [] arr = null;
        printArr(arr);//就会 接收到一个异常.
                        //这个方法没有处理方式,最终交给虚拟机处理
    }

    private static void printArr(int[] arr) {
        if(arr == null){
            //调用者知道成功打印了吗?
            //System.out.println("参数不能为null");
            throw new NullPointerException(); //当参数为null的时候
                                            //手动创建了一个异常对象,抛给了调用者,产生了一个异常
        }else{
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i]);
            }
        }
    }

}

最终会报错: 

 2.2    自己处理的方式

    (1)try-catch方式处理异常

  • 定义格式

    try {
        可能出现异常的代码;
    } catch(异常类名 变量名) {
        异常的处理代码;
    }
  • 执行流程

    • 程序从 try 里面的代码开始执行

    • 出现异常,就会跳转到对应的 catch 里面去执行

    • 执行完毕之后,程序还可以继续往下执行


        //好处:为了能让代码继续往下运行.
        int [] arr = null;
        try{
            //有肯能发现异常的代码
            printArr(arr);
        }catch (NullPointerException e){
            //如果出现了这样的异常,那么我们进行的操作
            System.out.println("参数不能为null");
        }


        System.out.println("嘿嘿嘿,我最帅!!!");

    }

    private static void printArr(int[] arr) {
        if(arr == null){
            throw new NullPointerException();
        }else{
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i]);
            }
        }

执行结果: 

 

好处:可以让程序继续往下执行

注意

  1. 如果 try 中没有遇到问题,怎么执行?

    会把try中所有的代码全部执行完毕,不会执行catch里面的代码

  2. 如果 try 中遇到了问题,那么 try 下面的代码还会执行吗?

    那么直接跳转到对应的catch语句中,try下面的代码就不会再执行了 当catch里面的语句全部执行完毕,表示整个体系全部执行完全,继续执行下面的代码

  3. 如果出现的问题没有被捕获,那么程序如何运行?

    那么try...catch就相当于没有写.那么也就是自己没有处理. 默认交给虚拟机处理.

  4. 同时有可能出现多个异常怎么处理?

    出现多个异常,那么就写多个catch就可以了. 注意点:如果多个异常之间存在子父类关系.那么父类一定要写在下面【多个catch的最后一个】

 

Throwable成员方法

  • 常用方法

    方法名说明
    public String getMessage()返回此 throwable 的详细消息字符串
    public String toString()返回此可抛出的简短描述
    public void printStackTrace()【常用】把异常的错误信息输出在控制台

    //public String getMessage​()    返回此 throwable 的详细消息字符串
    //public String toString​()      返回此可抛出的简短描述
    //public void printStackTrace​() 把异常的错误信息输出在控制台(字体为红色的) 



try {
            int [] arr = {1,2,3,4,5};
            System.out.println(arr[10]);
/*
虚拟机帮我们创建了一个异常对象
 new ArrayIndexOutOfBoundsException();  
再把此对象传递给Catch中的参数【e】,则e可以调用 throwable方法
*/


        } catch (ArrayIndexOutOfBoundsException e) {
            /*String message = e.getMessage();
            System.out.println(message);*/
           /* String s = e.toString();
            System.out.println(s);*/
           e.printStackTrace();
        }

        System.out.println("嘿嘿嘿");

 

自定义异常 

实现步骤
1. 定义异常类
2. 写继承关系
3. 提供空参构造
4. 提供带参构造

 自定义异常类:
        java提供的异常类,不够我们使用,需要自己定义一些异常类
    格式:
        public class XXXExcepiton extends Exception | RuntimeException{
            添加一个空参数的构造方法
            添加一个带异常信息的构造方法
        }
     注意:
        1.自定义异常类一般都是以Exception结尾,说明该类是一个异常类
        2.自定义异常类,必须的继承Exception或者RuntimeException
            继承Exception:那么自定义的异常类就是一个编译期异常,如果方法内部抛出了编译期异常,就必须处理这个异常,要么throws,要么try...catch
            继承RuntimeException:那么自定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理(中断处理)
 */
public class RegisterException extends /*Exception*/ RuntimeException{
    //添加一个空参数的构造方法
    public RegisterException(){
        super();//默认调用的父类的空参构造方法
    }

    /*
        添加一个带异常信息的构造方法
        查看源码发现,所有的异常类都会有一个带异常信息的构造方法,方法内部会调用父类带异常信息的构造方法,让父类来处理这个异常信息
     */
    public RegisterException(String message) {
        super(message);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值