Java_SE(三)异常处理

目录

一.  异常概述

1.1 异常概念

1.2 异常体系

1.2.1 Throwable体系

1.2.2 Throwable常用方法

1.3 常见异常分类

1.3.1 编译时期异常

1.3.2 运行时期异常

1.4 异常产生的原因和过程

1.4.1 异常原因

1.4.2 异常过程

二. 异常的处理

2.1 抛出异常throw

2.2 声明异常throws

2.3 捕获异常try-catch 

2.4 finally代码块

三. 自定义异常


一.  异常概述

1.1 异常概念

异常:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。

在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。而异常指的并不是语法错误,语法错了,编译不通过,就不会产生字节码文件,根本不能运行。

1.2 异常体系

1.2.1 Throwable体系

异常的根类是java.lang.Throwable,其下有两个子类:

  • java.lang.Error:用于指示合理的应用程序不应该试图捕获的严重问题,无法通过处理的错误,只能事先避免。
  • java.lang.Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的。

1.2.2 Throwable常用方法

  • public void printStackTrace():打印异常的详细信息。

        包含异常的类型、原因、异常出现的位置,在开发和调试阶段都得使用printStackTrace。

  • public String getMessage():获取发生异常的原因。

        提示给用户的时候,就提示错误原因。

  • public String toString():获取异常的类型和异常描述信息(不用)。

1.3 常见异常分类

一般说的异常是指Exception,这类异常一旦出现,我们就要对代码进行更正,修复程序。而Exception又分为CheckedException(编译期异常)和 RuntimeException(运行期异常)。

1.3.1 编译时期异常

在编译时期,就会检查,如果没有处理异常,则编译失败。常见的编译时期异常:

  • NoSuchMethodException:方法未找到异常
  • IOException:输入输出异常
  • EOFException:文件已结束异常
  • FileNotFoundException:文件未找到异常
  • NumberFormatException:字符串转换为数字异常
  • SQLException:操作数据库异常
  • ... ...

1.3.2 运行时期异常

在运行时期,检查异常,在编译时期,运行异常不会编译器检测(不报错)。常见的运行时期异常:

  • ArithmeticException:数学计算异常
  • NullPointerException:空指针异常
  • ArrayIndexOutOfBoundsException:数组索引越界异常
  • ClassNotFoundException:类文件未找到异常
  • ClassCastException:类型强制转换异常
  • SecurityException:违背安全原则异常
  • ... ...

1.4 异常产生的原因和过程

1.4.1 异常原因

  1. 编写程序代码中的错误产生的异常,比如数组越界、空指针异常等,这种异常叫做未检查的异常,一般需要在类中处理这些异常。
  2. Java内部错误发生的异常,Java虚拟机产生异常。
  3. 通过throw(抛出异常)语句手动生成的异常,这种异常叫做检查的异常,一般是用来给方法调用者一些必要的信息。

1.4.2 异常过程

先运行下面的程序,程序会产生一个数组索引越界异常ArrayIndexOfBoundsException。我们通过图解来解析下异常产生的过程。

工具类

public class ArrayTools {
    // 对给定的数组通过给定的角标获取元素。
    public static int getElement(int[] arr, int index) {
        int element = arr[index];
        return element;
    }
}

测试类

public class ExceptionDemo {
    public static void main(String[] args) {
        int[] arr = { 34, 12, 67 };
        intnum = ArrayTools.getElement(arr, 4)
        System.out.println("num=" + num);
        System.out.println("over");
    }
}

上述程序执行过程图解:

二. 异常的处理

Java异常处理的几个关键字:try-catchfinallythrowthrows

2.1 抛出异常throw

throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。

使用格式及示例:

throw new 异常类名(参数);

//例如

throw new NullPointerException("要访问的arr数组不存在");

throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围");
public class ThrowDemo {
    public static void main(String[] args) {
        //创建一个数组 
        int[] arr = {2,4,52,2};
        //根据索引找对应的元素 
        int index = 4;
        int element = getElement(arr, index);

        System.out.println(element);
        System.out.println("over");
    }
    /*
     * 根据索引找到数组中对应的元素
     */
    public static int getElement(int[] arr,int index){ 
       	//判断索引是否越界
        if(index<0 || index>arr.length-1){
             /*
             判断条件如果满足,当执行完throw抛出异常对象后,方法已经无法继续运算。
             这时就会结束当前方法的执行,并将异常告知给调用者。这时就需要通过异常来解决。 
              */
             throw new ArrayIndexOutOfBoundsException("小胖友,下标越界了~~~");
        }
        int element = arr[index];
        return element;
    }
}

2.2 声明异常throws

声明异常:将问题标识出来,报告给调用者。关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。

使用格式及示例:

修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{   }    

public class ThrowsDemo {
    public static void main(String[] args) throws FileNotFoundException {
        read("a.txt");
    }

    // 如果定义功能时有问题发生需要报告给调用者。可以通过在方法上使用throws关键字进行声明
    public static void read(String path) throws FileNotFoundException {
        if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 
            // 我假设  如果不是 a.txt 认为 该文件不存在 是一个错误 也就是异常  throw
            throw new FileNotFoundException("文件不存在");
        }
    }
}

throws用于进行异常类的声明,若该方法可能有多种异常情况产生,那么在throws后面可以写多个异常类,用逗号隔开。  

public class ThrowsDemo2 {
    public static void main(String[] args) throws IOException {
        read("a.txt");
    }

    public static void read(String path)throws FileNotFoundException, IOException {
        if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 
            // 我假设  如果不是 a.txt 认为 该文件不存在 是一个错误 也就是异常  throw
            throw new FileNotFoundException("文件不存在");
        }
        if (!path.equals("b.txt")) {
            throw new IOException();
        }
    }
}

2.3 捕获异常try-catch 

捕获异常:Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式的处理。try-catch的方式就是捕获异常。

捕获异常语法如下:

try{
     编写可能会出现异常的代码
}catch(异常类型  e){
     处理异常的代码
     // 记录日志/打印异常信息/继续抛出异常

     // 用来进行某种异常的捕获,实现对捕获到的异常进行处理
}

注意:try和catch都不能单独使用,必须连用。

public class TryCatchDemo {
    public static void main(String[] args) {
        try {// 当产生异常时,必须有处理方式,要么捕获,要么声明。
            read("b.txt");
        } catch (FileNotFoundException e) {
          	//try中抛出的是什么异常,在括号中就定义什么异常类型
            System.out.println(e);
        }
        System.out.println("over");
    }
    
    // 我们当前的这个方法中有编译期异常
    public static void read(String path) throws FileNotFoundException {
        if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 
            // 如果不是 a.txt 则认为该文件不存在,就是一个异常throw
            throw new FileNotFoundException("文件不存在");
        }
    }
}

2.4 finally代码块

finally块:定义在异常处理机制中的最后一块。可以直接跟在try之后,或者最后一个catch之后。finally可以保证只要程序执行到了try语句块中,无论try语句块中的代码是否出现异常,最终finally都必定执行。通常用来做释放资源这类操作。

finally的语法:

try...catch....finally:自身需要处理异常,最终还得关闭资源。

注意:finally不能单独使用

public class TryCatchDemo4 {
    public static void main(String[] args) {
        try {
            read("a.txt");
        } catch (FileNotFoundException e) {
            //抓取到的是编译期异常,抛出去的是运行期 
            throw new RuntimeException(e);
        } finally {
            System.out.println("不管程序怎样,这里都将会被执行。");
        }
        System.out.println("over");
    }

    public static void read(String path) throws FileNotFoundException {
        if (!path.equals("a.txt")) {
            throw new FileNotFoundException("文件不存在");
        }
    }
}

三. 自定义异常

上述异常都是JDK内部定义好的,但是实际开发中也会出现很多在JDK中没有定义过的异常,例如年龄负数问题、考试成绩负数问题等,那么就需要我们自定义这些异常。

自定义异常的一些规则:

public class ThrowsDemo {
    public void dosome() throws IOException, AWTException {
    }
}

class SubClass extends ThrowsDemo {
    //public void dosome()throws IOException, AWTException {}

    // 允许子类方法不再抛出任何异常
    // public void dosome(){}

    // 允许子类方法抛出部分异常
    // public void dosome()throws IOException{}

    // 允许子类方法抛出超类方法声明异常的子类型异常
    // public void dosome()throws FileNotFoundException {}

    // 不允许子类抛出额外异常(超类方法上没有的且没有继承关系的异常)
    // public void dosome()throws SQLException {}

    // 不允许子类抛出比超类方法声明的异常还大的异常
    // public void dosome()throws Exception {}

}


本文完!

写在结尾:

2022 年 9 月 27 日  一个java菜鸟,发布于北京海淀。

好记性不如烂笔头,持续学习,坚持输出~今天是持续写作的第8天。可以点赞、评论、收藏啦。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码云说

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

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

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

打赏作者

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

抵扣说明:

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

余额充值