Java异常的分类;异常的处理方式:声明异常、抛出异常、自己处理异常;自定义异常类

1. 异常的体系结构和异常的分类

异常就是程序出现了不正常的情况,导致JVM非正常终止,代码语法错误不在异常体系之中。

异常的体系结构:

  • 编译时异常:在编译成class文件时必须要处理的异常,也称为受检异常
  • 运行时异常:在编译过程中不需要处理,在运行字节码文件时可能会出现的异常

2. JVM默认处理异常的方式

当代码出现了异常,那么就会在异常处创建一个异常对象,若程序没有自己处理异常的代码,就会将异常交给本方法的调用者处理。

JVM默认处理异常的方式:

  • 将异常信息以红色字体展示在控制台上(异常原因、名字 、位置)
  • 停止程序运行,哪里出现异常就在哪里停止

3. 异常处理方式

3.1 throws声明异常

格式:public void 方法() throws 异常类名

注意事项:

  • 书写位置在方法的括号后面,表示声明一个异常
  • 编译时异常必须要进行处理,throws声明异常表示,谁调用这个方法谁处理异常
  • 运行时异常因为在运行时才会发生,所以在方法后面可以不写,默认交给jvm处理

示例代码:

public class Demo02 {
    public static void main(String[] args) throws ParseException {
        method1();//如果调用者没有处理异常的代码,最终交给Main方法调用者JVM处理异常
    }

    //throws声明,告诉调用者调用这个方法可能会发生异常
    //若无异常,方法正常执行;若发生异常将异常交给调用者处理
    private static void method1() throws ParseException {
        String s = "2021年11月11日";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        Date d = sdf.parse(s);//有可能会产生异常
        System.out.println(d);
    }
}

3.2 throw抛出异常

  • 格式:throw new 异常();
  • 注意:这个格式是在方法内的,表示当前代码手动抛出一个异常,下面的代码不用再执行了

throws和throw的区别:

throwsthrow
用在方法声明后面,跟的是异常类名用在方法体内,跟的是异常对象名
表示声明异常,调用该方法有可能会出现这样的异常表示手动抛出异常对象,由方法体内的语句处理

抛出异常的意义:

  • 在方法中,当传递的参数有误,没有继续运行下去的意义了,则采取抛出处理,表示让该方法结束运行
  • 告诉调用者方法中出现了问题
public class ExceptionDemo {
    public static void main(String[] args) {
        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]);
            }
        }
    }

}

3.3 try-catch自己处理异常

此方法处理异常的好处:即使发生了异常,程序还可以继续执行

示例代码:

public class Demo01 {
    public static void main(String[] args) {
        int[] arr = null;
        try {
            //有可能会出现异常的代码
            printArr(arr);
        }catch (NullPointerException e){
            //若出现了这样的异常,我们进行的操作
            System.out.println("数组为空");
        }
        //程序不会终止,会继续执行
        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]);
            }
        }
    }
}

注意事项:

  • 如果 try 中没有遇到异常,会把try中所有的代码全部执行完毕,不会执行catch里面的代码
  • 如果 try 中遇到了异常,那么直接跳转到对应的catch语句中,try下面的代码就不会再执行了
  • 如果出现的异常没有被捕获,那么try...catch就相当于没有写,异常默认交给虚拟机处理
  • 若出现多个异常就写多个catch,如果多个异常之间存在子父类关系,那么父类要写在子类异常的下面

4. Throwable类常用方法和自定义异常类

Throwable常见方法:

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

自定义异常类:

  • 当Java中提供的异常不能满足我们的需求时,我们可以自定义异常,让异常信息更加的见名知意
  • 实现步骤: 1. 定义异常类;2. 写继承关系;3. 提供空参构造;4. 提供带参构造

练习

案例需求:

  • 键盘录入学生的姓名和年龄,其中年龄为18 - 25岁;
  • 超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止

自定义异常AgeOutOfBoundsException

public class AgeOutOfBoundsException extends RuntimeException {
    public AgeOutOfBoundsException() {
    }

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

创建学生对象代码:在setAge方法中判断年龄抛出自定义异常AgeOutOfBoundsException

package com.yulu.yichang;

public class Student {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age >= 18 && age <= 25){
            this.age = age;
        }else {
            //如果Java中提供的异常不能满足我们的需求,我们可以使用自定义的异常
            throw new AgeOutOfBoundsException("年龄超出范围!");
        }

    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student() {
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

键盘录入姓名和年龄,并赋值给学生对象,如果是非法数据就再次录入

package com.yulu.yichang;

import java.util.Scanner;

public class ExceptionDemo {
    public static void main(String[] args) {
        Student student = new Student();
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生姓名:");
        String name = sc.nextLine();
        student.setName(name);
        while(true){
            System.out.println("请输入学生年龄:");
            String strage = sc.nextLine();
            try {
                int age = Integer.parseInt(strage);
                student.setAge(age);
                //无异常则退出循环
                break;
            } catch (NumberFormatException e) {
                //针对int age = Integer.parseInt(ageStr);捕获异常
                System.out.println("请输入一个整数");
                continue;
            } catch (AgeOutOfBoundsException e){
                //针对Student类中年龄限制抛出异常
                System.out.println(e.toString());
                System.out.println("请输入一个18-25岁的年龄");
                continue;
            }
        }
        //打印学生对象字符串(toString)
        System.out.println(student);
    }
}

 

如有错误欢迎留言评论,及时更正。 2021年5月28日 羽露风

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羽露风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值