异常的详解

  在Java中,将程序执行过程中发生的不正常行为称为异常

一、异常的体系结构

       异常种类繁多,为了对不同的异常或者错误进行很好的分类管理,Java内部维护了一个异常的体系结构

从上图可以看到:

   1、Throwable:是异常体系的顶层类,其派生出两个重要的子类:Error和Exception

    2、Error:指的是Java虚拟机无法解决的严重问题,典型代表:StackOverflowError和OutOfMemoryError

    //java.lang.StackOverflowError
    public static void method5(){
        method5();
    }

    //java.lang.OutOfMemoryError
    public static void method6(){
        int[] arr = new int[1024*1024*1024];
    }

    3、Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行

二、异常的分类

      异常可能在编译时出现,也可能在程序运行时发生,根据发生的时机不同,可以将异常分为:

       1、编译时异常

            在编译期间发生的异常,称为编译时异常,也称为受检查异常

           

public class Person implements Cloneable{
    String name;
    int age;
    String gender;

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

    @Override
    public Person clone() throws CloneNotSupportedException {
        return new Person(name,age,gender);
    }
}
public class TestPerson {
    public static void main(String[] args) {
        Person p1 = new Person("jim",18,"男");
        //Person p2 = p1.clone(); //编译时异常
    }
}

        2、运行时异常

              在程序执行期间发生的异常,称为运行时异常,也称为非受检查异常

               RunTimeException以及其子类对应的异常,都称为运行时异常,以下为经典例子:

               1)算数异常

算数异常
    public static void method1(){
        System.out.println(10/0);
    }

               2)数组越界异常

数组越界异常
    public static void method2(){
        int[] nums = {1,2,3};
        System.out.println(nums[nums.length]);
    }

              3)空指针异常

空指针异常
    public static void method3(){
        int[] nums = null;
        System.out.println(nums[0]);
    }

               4)不匹配

public static void method4(){
        Scanner sc = new Scanner(System.in);//输入“hello”
        int data = sc.nextInt();//java.util.InputMismatchException
        System.out.println(data);
        sc.close();
    }

三、异常的处理

      1、防御式编程:在程序出现问题的时候及时通知程序猿,主要的方式有:

            1)LBYL:Look Before You Leap:在操作之前就做充足的检查,即事前防御型(if   else)

            2)EAFP:遇到问题在处理,即事后认错型(try catch)(推荐)

public class Main1 {
    static int[] a = new int[10];

    public static int method(int index){
        //下标越界
        if(index < 0 || index >= a.length){
            throw new ArrayIndexOutOfBoundsException("下标越界");//异常抛出
        }
        return a[index];
    }

    public static void main(String[] args) {
        //运行时异常一般不处理,就是需要暴露出问题然后给出提示
        try {
            System.out.println(method(100));
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }

    }
}

注:在Java中,异常处理主要的5个关键字:throw、try、catch、final、throws

     2、异常的抛出

          在编写程序时,如果程序中出现错误,此时需要将错误的信息告知给调用者

           在Java中,可以借助throws关键字,抛出一个指定的异常对象,将错误信息告知给调用者

throw new XXXException("异常产生的原因")
public class Main {
    static int[] a = new int[10];

    public static int method(int index){
        //下标越界
        if(index < 0 || index >= a.length){
            throw new ArrayIndexOutOfBoundsException("下标越界");//异常抛出
        }
        return a[index];
    }

    public static void main(String[] args) {
        method(100);
    }
}

  注意: 

           1、throw必须写在方法体内部

           2、抛出的对象必须是Exception或者Exception的子类对象

           3、如果抛出的是RunTimeException或者其子类对象,可以不用处理,交给JVM

           4、如果抛出的是编译时异常,则用户必须处理,否则无法通过编译

           5、异常一旦抛出,其后的代码就不会执行

四、异常的捕获

        异常的捕获,也就是异常的具体处理方式,主要有两种:异常声明throws以及try-catch捕获处理

        1、异常声明throws

                处在方法声明参数列表之后,当方法抛出编译时异常时,用户不想处理该异常,此时就可以借助throws关键字给方法的调用者来处理,即当前方法不处理异常,提醒方法的调用者处理异常

@Override
    public Person clone() throws CloneNotSupportedException {
        return new Person(name,age,gender);
    }

        注意:

                 1、throws必须跟在方法的参数列表之后

                 2、声明的异常必须是Exception或者其子类

                 3、方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型具有父子关系 ,直接声明父类即可

                  4、调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出

        2、try-catch捕获并处理

              如果真正处理,就需要try-catch

try{
    //将可能出现异常的代码放在这里
} catch(要捕获的异常类型 e){
    //对异常进行处理
} finally{
    //此处代码一定会被执行到
}

//后序代码
//当异常被捕获到时,异常就被处理了,这里的后续代码一定会执行
/如果捕获了,由于捕获时类型不对,那就没有捕获到,这里的代码就不会被执行
//try中的代码可能会抛出异常,也可能不会

   注意:

          1、try块内抛出异常位置之后的代码将不会被执行

          2、如果抛出异常类型与catch时异常类型不匹配,即异常不会被成功捕获,也就不会被处理

          3、try可能会抛出多个不同的异常对象,则必须用多个catch来捕获,即多种异常,多次捕获

          4、可以通过一个catch捕获所有的异常,即多个异常一次捕获(不推荐) 

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

薰衣草2333

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

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

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

打赏作者

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

抵扣说明:

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

余额充值