JAVA基础知识(六)

异常

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

异常就是程序出现了不正常的情况。

语法错误不算在异常体系中。

 简单来说:编译时异常就是在编译时出现的异常;运行时异常就是在运行时出现的异常。

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

  • 编译时异常

    • 都是Exception类及其子类

    • 必须显式处理(手动处理),否则程序就会发生错误,无法通过编译

  • 运行时异常

    • 都是RuntimeException类及其子类

    • 无需显式处理(手动处理),也可以和编译时异常一样处理

 3、异常处理

3.1JVM默认处理异常的方式

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

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

  • 程序停止执行

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



    }
}

3.2throws方式处理异常

定义格式 声明异常->说明一下有异常

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

 注意事项:编译时的异常,必须声明,谁调用谁处理,最后让jvm来处理,运行时异常可以不声明。

3.3throw抛出异常

格式:throw new 异常();

注意事项:

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

抛出处理异常的意义:

在方法中,当传递的参数有误时,没有继续运行的必要了,采取抛出处理,表示该方法结束

然后告诉调用者方法中出现了问题。

throws和throw的区别:

throwsthrow
用在方法声明后面,跟的是异常类名用在方法体内,跟的是异常对象名
表示声明异常,调用该方法有可能会出现这样的异常表示手动抛出异常对象(百分百抛出异常)
可以声明多个异常只能有一个

 3.4try-catch自己处理异常

定义格式

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

执行流程:

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

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

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

代码演示:

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

        //好处:为了能让代码继续往下运行.
        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]);
            }
        }
    }
}

 3.5try-catch常见问题

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

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

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

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

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

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

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

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

4、Throwable中的常见方法

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

代码演示:

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

        try {
            int [] arr = {1,2,3,4,5};
            System.out.println(arr[10]);//虚拟机帮我们创建了一个异常对象 new ArrayIndexOutOfBoundsException();
        } catch (ArrayIndexOutOfBoundsException e) {
            /*String message = e.getMessage();
          System.out.println(message);*/
           /* String s = e.toString();
            System.out.println(s);*/
           e.printStackTrace();
      }

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

  }
}

5、自定义异常

5.1什么是自定义异常?

当Java中提供的异常不能满足我们的需求时,我们可以自定义异常

5.2为什么要 自定义异常?

有一个原则 :异常类要与业务相关

5.3实现步骤

        (1)定义异常类

        (2)写继承关系

        (3)提供空参构造

        (4)提供带参构造

代码实现

异常类

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

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

 学生类

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

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = 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("年龄超出了范围");
        }
    }

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

测试类

public class ExceptionDemo12 {
    public static void main(String[] args) {
        // 键盘录入学生的姓名和年龄,其中年龄为 18 - 25岁,
        // 超出这个范围是异常数据不能赋值.需要重新录入,一直录到正确为止。

        Student s = new Student();

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入姓名");
        String name = sc.nextLine();
        s.setName(name);
       while(true){
           System.out.println("请输入年龄");
           String ageStr = sc.nextLine();
           try {
               int age = Integer.parseInt(ageStr);
               s.setAge(age);
               break;
           } catch (NumberFormatException e) {
               System.out.println("请输入一个整数");
               continue;
           } catch (AgeOutOfBoundsException e) {
               System.out.println(e.toString());
               System.out.println("请输入一个符合范围的年龄");
               continue;
           }
           /*if(age >= 18 && age <=25){
               s.setAge(age);
               break;
           }else{
               System.out.println("请输入符合要求的年龄");
               continue;
           }*/
       }
        System.out.println(s);

    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值