java异常

目录

一. 异常概述

1. 什么是异常

2. java中默认的异常处理机制

二. 异常处理

1. 方式一

1.1 try关键字

1.2 catch关键字

1.3 finally关键字

1.3.1 finally案例一

1.3.2 finally案例二

1.3.3 finally案例三

2. 方式二

2.1 throws关键字

2.2 throw关键字

 三. 编译期异常和运行时异常

四. 异常体系结构

五. 自定义异常


一. 异常概述

1. 什么是异常

异常:是指程序在运行过程中出现的不正常情况

注意:代码写错了(编译期间检查出来的错误),不属于异常的范围

2. java中默认的异常处理机制

java为每个可能出现的异常情况封装了一个类,当出现异常时,会抛出该类的对象,并终止jvm(虚拟机)的运行,当然我们程序员可以预测可能会出现异常,并利用异常处理机制对异常进行捕获,从而使程序能够正常执行完毕,这也是下面要讲的

二. 异常处理

java中提供了一些办法,让程序员对可能出现的异常进行提前的处理,避免后续程序无法执行

1. 方式一

1.1 try关键字

try{

//try中经常写一些可能会出现异常的代码(这个要靠经验)  

}

try{}块主要用来检测异常,其中可以写一些可能出现异常的代码(要靠经验),当检测到异常时try块中后续的代码将不会执行,直接跳到catch(){}语句块中捕获该异常

1.2 catch关键字

把try中检测到的异常与catch中的异常类型进行匹配,保证程序可以进行下去,catch块必须紧跟在try块后面,如果匹配成功,继续执行catch块中的内容,如果匹配不成功,则会由jvm将异常信息打印到控制台程序结束,当然,一个try后可跟多个catch来捕获不同类型的异常,但异常的类型必须有子类到父类的顺序写,否则会编译出错

try{

//可能出现异常的代码

}catch(异常类型1){

//对该异常的处理

}catch(异常类型2){

//对该异常的处理

}catch(异常类型3){

//对该异常的处理

}

//后续代码

1.3 finally关键字

finally{}块中的代码不管是发生异常还是没发生异常都会被执行,finally块可写可不写

try{

//可能出现异常的代码

}catch(异常类型1){

//对该异常的处理

}catch(异常类型2){

//对该异常的处理

}catch(异常类型3){

//对该异常的处理

}finally{

//必须要执行的代码

}

//后续代码

下面举三个案例来说明什么是必须会被执行的代码

1.3.1 finally案例一

场景一:异常没有被成功捕获(即catch没有成功匹配到异常),那么jvm会在控制台打印出异常信息,程序被终止,但在这之前,会执行finally中的语句

public class Demo5 {

  //场景1 异常没有被捕获到,后面的代码无法执行,但是finally中的代码是可以执行的

    public static void main(String[] args) throws IOException {

        try{

            int num = Integer.parseInt("10a");

        }catch (ArrayIndexOutOfBoundsException e){

            e.printStackTrace();

        }finally{

            System.out.println("qqqqqqqqqqqqqqqq");

        }

        System.out.println("aaaaaaaaaaaaaaa");*/

     }
}

可以看到这里虽然发生了数字格式化异常,但是在程序终止前,还是先执行了finally块中的代码

1.3.2 finally案例二

当我们正在读取硬盘上的文件时,如果因为各种原因而发生异常,而我们又必须要执行关闭流的操作,就可以将关闭流的操作写到finally中

//场景2 确保在出现异常的情况下 依然最终把流对象关闭掉
public class Demo5 {

        FileInputStream in = null;

        try{

            in = new FileInputStream("H:/demo.txt");

        } catch (FileNotFoundException e) {

            e.printStackTrace();
            System.out.println("文件找不到异常");

        }finally{

            if(in!=null){
                in.close();
            }
        }
        System.out.println("aaaaaaaaaaaaaa");
    }
}

注意:

1.如果将关闭流的操作写到try中,那么很可能在关闭流之前就发生异常,从而导致程序转而执行catch语句而没有关闭流

2.如果将关闭流的操作写到catch()语句中,那么如果程序没有发生异常,则无法执行catch语句,从而无法关闭流

3.如果在try和catch中都写关闭流的操作,虽然可以解决问题,但会造成代码冗余

所以最终解决的方案就是将关闭流的操作写到finally语句块中

1.3.3 finally案例三

当我们在有返回值的函数中写了finally语句块,无论是try中还是catch进行return,也必须在return之前,先执行finally代码块

public class Demo6 {

//场景3 无论是try中还是catch进行return,也必须在return之前,先执行finally代码块
    
    public static void main(String[] args) throws IOException {
        test(10,0);
        System.out.println("aaaaaaaaaaaaaaaaaaa");
    }

    public static int test(int a,int b){
        try{
            int c = a / b;
            return c;
        }catch (ArithmeticException e){
            e.printStackTrace();
            System.out.println("算术异常");
            return -1;
        }finally{
            System.out.println("关闭流");//关闭流操作
        }
    }
}

2. 方式二

2.1 throws关键字

throws用于在一个方法内部可能会出现异常,但是在这个方法内不想用try{}catch{}语句块处理,那么就用throws将该异常抛出,在调用这个方法的地方处理或再抛出,但是最多只能抛到main方法,如果再抛就会抛给jvm,jvm就会终止程序,达不到处理异常想让程序正常往下执行的效果,所以我们一般规定,最多抛到main方法就要用try{}catch{}去处理异常

public class Demo7 {

       //main方法
    public static void main(String[] args){

          //最好在main方法中处理了

        try {
            methodA();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println("该路径不存在此文件");
        }
        System.out.println("main");
    }


         //方法二 methodA()
        public static void methodA () throws FileNotFoundException {
            methodB();
            System.out.println("methodA");
        }



          /*
          用methodB方法模拟一个底层方法
          throws 异常类型 声明表示此方法中可能会出现给定的异常,并且该方法不处理异常
          谁调用谁处理
          */


        //方法三 methodB()可能出现异常
        public static void methodB () throws FileNotFoundException {
            FileInputStream inputStream = new FileInputStream("H:/demo.txt");
            System.out.println("methodB");
        }

}

注意:

1. throws后面可以抛出多个异常

2. 任何方法都可以使用throws抛出,包括抽象方法

3.如果抛出的是运行期异常,那么不会有任何提示,需要自己看所调用的方法结构

2.2 throw关键字

throw关键字用于方法内部,当不满足条件时,自己主动的抛出一个异常对象,并通过构造方法将异常原因传给Throwable类的message成员变量,终止该方法的运行

public class Demo10 {
    public static void main(String[] args) {
        try {
            char c = level(101);
        } catch (ScoreException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        System.out.println("qqqqqqqqqqqqqqqq");
    }

    /*
    throws:用在一个方法名后,表示此方法可能存在异常,并且不处理
    throw:用在一个方法内部,表示不满足某条件时,抛出一个异常对象,并将出错信息通过构造方法传入,终止当前方法
     */
    public static char level(int score) throws ScoreException
    {
        if(score<0||score>100)
        {
            throw new ScoreException("非法的分数");//当不满足某条件时,程序中主动的抛出异常对象,终止此方法继续向下进行,通过异常的构造方法传入异常原因
        }
        if(score>=90&&score<=100)
        {
            return 'A';
        }else{
            return 'B';
        }
    }
}

 三. 编译期异常和运行时异常

编译期异常:直接或间接继承Exception类的异常,该类的异常会在编写代码时由编译器显示报错,指出要对其进行处理,eg:FileNotFoundException等

运行期异常:继承了RunTimeException类的异常,该类的异常不会在编写代码时提示,只有当实际运行中导致了该异常,终止了程序,才会在控制台打印,eg:ArrayIndexOutOfBoundsException等

四. 异常体系结构

 

五. 自定义异常

当java提供的异常类不满足我们的业务需求时,我们需要自己定义一个异常类,来达到让程序在发生不正常现象时可以向用户给一定的提示性信息,使程序有一定的健壮性

一个类要想是异常类,那么只需要继承Exception或RunTimeException,继承编译期异常(Exception),那么该自定义的异常类会在编译时由编译器提示要处理异常,而继承运行时异常则只在运行时发生异常才会输出到控制台,并终止程序运行,需要程序员自己判断并做出相应的处理,这两种异常可以根据自己的需要,继承其中一个即可,继承后一定要重写带String的有参构造,可以将异常信息通过构造方法,传递给父类

public class ScoreException extends Exception{
    //根据自己的业务需求自己定义异常类

    /*
        分数自定义异常
        当分数不合法时抛出此类的对象
        例如百分制分数,分数小于0大于100时抛出
     */

    public ScoreException(String message) {
        super(message);
    }
}
public class Demo10 {
    public static void main(String[] args) {
        try {
            char c = level(101);
        } catch (ScoreException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        System.out.println("qqqqqqqqqqqqqqqq");
    }

   
    public static char level(int score) throws ScoreException
    {
        if(score<0||score>100)
        {
            throw new ScoreException("非法的分数");
        }

        if(score>=90&&score<=100)
        {
            return 'A';
        }else{
            return 'B';
        }
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值