第二十一章、JavaSE专题之异常详述

本文详细介绍了Java中的异常处理机制,包括异常的分类、常见的运行时异常如空指针、数学运算、数组下标越界和类型转换异常。通过实例展示了try-catch-finally的使用,并解释了如何通过throws关键字处理异常。此外,还探讨了自定义异常的创建以及throw和throws的区别。
摘要由CSDN通过智能技术生成

1、异常概述

1.1、异常引入
package exception;

public class Excep1 {
    public static void main(String[] args) {
        int num1 = 1;
        int num2 = 0;
        //1、num1 / num2 => 1/0
        //2、当执行到num1 / num2 因为num2 = 0,程序就会出现(抛出)异常 ArithmeticException
        //3、当抛出异常后,程序就退出,崩溃了,下面代码就不会执行
        //4、大家想想这样的程序好吗?不好,不应该出现了一个不算致命的问题,就到整个系统崩溃
        //5、java程序设计这,提供了 异常处理机制来解决问题;
        int res = num1 / num2;
        System.out.println("程序继续运行...");
    }
}
  • 运行结果

在这里插入图片描述

1.2、异常入门
  • 作用:如果进行异常处理,那么即使程序出现了异常,程序可以继续执行
  • 定义方式:异常处理机制如果认为一段代码可能出现异常/问题,可以使用try-catch异常处理机制来解决
public class ExceptionSource {
    public static void main(String[] args) {
        int num1 = 1;
        int num2 = 0;
        //1、num1 / num2 => 1/0
        //2、当执行到num1 / num2 因为num2 = 0,程序就会出现(抛出)异常 ArithmeticException
        //3、当抛出异常后,程序就退出,崩溃了,下面代码就不会执行
        //4、大家想想这样的程序好吗?不好,不应该出现了一个不算致命的问题,就到整个系统崩溃
        //5、java程序设计这,提供了 异常处理机制来解决问题;
        try {
            int res = num1 / num2;
        } catch (Exception exception) {
            System.out.println(exception.getMessage());
        }

        System.out.println("程序继续运行...");
    }
}
  • 运行结果

在这里插入图片描述

1.3、异常介绍
  • 异常:java语言中,将程序执行中发生的不正常情况称为“异常”

  • 异常事件的分类

    • Error(错误):java虚拟机无法解决的严重问题;
      • Error是严重错误,程序会崩溃;
    • Exception(异常):编程错误或偶然的外在原因导致的一般性问题;
      • Exception分类:运行时异常和编译时异常
  • 异常类图如下:

在这里插入图片描述

2、常见异常 - 运行时异常

2.1、空指针异常
  • 空指针异常:NullPointException
  • 范例
public class Excep1 {
    public static void main(String[] args) {
        String name = null;
        System.out.println(name.length());
	}
}
  • 运行异常

在这里插入图片描述

2.2、数学运算异常
  • 数学运算异常:ArithmeticException
  • 范例
public class ExceptionSource {
    public static void main(String[] args) {
        int num1 = 1;
        int num2 = 0;
        int res = num1/num2;
    }
}
  • 运行结果

在这里插入图片描述

2.3、数组下标越界异常
  • 数组下表越界异常:ArrayIndexOutOfBoundsException
  • 范例
public class ExceptionSource {
    public static void main(String[] args) {
        int[] arr = new int[5];
        arr[10] = 7;
        System.out.println("end of main() method!");
    }
}
  • 运行结果

在这里插入图片描述

2.4、类型转换异常
  • 类型转换异常:ClassCastException

  • 范例

public class ExceptionSource {
    public static void main(String[] args) {
        A b = new B(); //向上转型
        B b2 = (B)b;   //向下转型
        C c2 = (C)b;   //抛出异常ClassCastException
    }
}

class A{}
class B extends A{}
class C extends A{}
  • 运行结果

在这里插入图片描述

2.5、数字格式不正确异常
  • 数字格式不正确异常:NumberFormatException
  • 范例:
public class ExceptionSource {
    public static void main(String[] args) {
        String name = "离职";
        //将String转成int
        int num = Integer.parseInt(name); //抛出NumberFormatException
        System.out.println(num);
    }
}
  • 运行结果

在这里插入图片描述

3、编译异常

3.1、文件操作

(1)IOEException:操作文件发生异常,由失败或中断的I / O操作产生的一般异常类;

(2)FileNotFoundException:当操作一个不存在的文件时,发生异常;

(3)EOFException:操作文件到文件末尾,发生异常;

3.2、数据库操作

(1)SQLException:查询数据库时,查询表可能发生异常;

3.3、网络波动

(1)java.net.SocketTimeoutException:socket超时错误,超时分为连接超时和读取超时;

(2) java.net.SocketException: Too many open files:指进程打开文件句柄数超过限制,当并发用户数比较大时,服务器可能会报这个异常。

4、异常处理机制

  • 1、try - catch - finaly和throws二选一;
  • 2、如果没有显式处理异常,则默认是throws;
4.1、try-catch-finally
  • 异常处理流程

    • 1、发生异常
    • 2、系统将异常封装成Exception对象e,传递给catch
    • 3、得到异常对象后,程序员自行处理,没有发生异常则catch代码块不执行;
    • 4、不管try代码块有没有发生异常,始终要执行finally
      • finaly:通常防止要释放资源的代码,比如文件、数据库、网络等的关闭。
  • 基本语法

try{
    //可疑代码
    //将异常生成对应的异常对象,传递给catch块
}catch(异常){
    //对异常的处理
}

(1)范例一

public class ExceptionSource {
    public static void main(String[] args) {
        try {	// 检查这个程序的代码
            int[] arr = new int[5];
            arr[10] = 7;	// 这里会出现异常
            System.out.println("不发生异常时打印");
        }
        catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("发生异常时执行catck : 数组超出绑定范围!");
        }
        finally {	// 这个程序的代码一定会执行
            System.out.println("代码一定会执行 :end of main() method!");
        }
    }
}
  • 运行结果

在这里插入图片描述

  • 异常处理细节

    (1)如果异常发生了,则异常发生后面的代码不会执行直接进入到catch块

    (2)如果异常没有发生则顺序执行try的代码块,不会进入catch;

    (3)如果希望不管是否发生异常,都执行某块代码块(比如关闭连接,释放资源等),则使用finaly;

    (4)如果有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,发生异常只会匹配一个catch。

    ​ 因为在用catch捕获异常的时候,会根据catch()中的内容逐个执行,当发现到try中产生的异常和catch内的异常相同时候就会停止。

(2)范例:多catch时,catch异常捕获范围从小到大,只会捕获一次

//1、创建ExampleA类继承异常父类
package exception;

class ExampleA extends Exception{
    private String a=null;
    //这里必须加上无参的构造函数,因为自己定义了有参的构造函数,则会覆盖原来无参构造函数
    //但是子类构造对象时候会先调用父类的构造函数,其中会默认先调用super方法,该方法是调用父类的无参构造函数,若没有定义就会报错
    public ExampleA(){}//所以必须写出无参的构造函数,写了有参就要写无参,除非程序不再调用无参的,否则调用就会报错
    public ExampleA(String a){
        this.a=a;
    }
}


//2、创建ExcepleB类继承ExcepleA父类
//当构造对象时候就会默认调用super方法,先调用父类的无参构造函数,super默认调用的

class ExampleB extends ExampleA{
    private String b=null;
    public ExampleB(String b){
        this.b=b;
    }
}

//3、创建main方法
//最后的输出仅仅只是Example
public class ExceptionSource {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //这里抛出一个ExampleB类对象的一个异常
        try {
            throw new ExampleB("b");
            //这里先catch该父类ExampleA中异常
        } catch (ExampleA e) {
            //若捕获到就输出EXampleA
            System.out.println("捕获父类异常:ExampleA");
            //这里数ExampleA的父类,但是这里捕获不到异常new ExampleB(“b”)异常了,因为异常已经被子类ExampleA捕获走了,除非子类捕获不到的异常才会执行捕获
            //但是如果先catch父类的异常,子类的异常就会失效,不会执行
        } catch (Exception e) {
            //所以该catch语句就不会执行了,即不会再输出”Example“
            System.out.println("捕获子类异常:ExampleB");
        }
    }

}
  • 运行结果

在这里插入图片描述

(3)最佳实践

import java.util.Scanner;

public class ExceptionSource {
    public static void main(String[] args) {
        //1、创建scanner对象;
        //2、使用无限循环,去接受一个输入;
        //3、然后将该输入的指,转成一个int
        //4、如果在转换时,输出一场,说明输入的内容不是一个可以转成int的内容
        //5、如果没有抛出异常,则break该循环
        Scanner scanner = new Scanner(System.in);
        int num = 0;
        String inputStr = "";
        while(true){
            System.out.println("请输入一个整数:");
            inputStr = scanner.next();
            try{
                num = Integer.parseInt(inputStr);  //这里可能抛1出异常
                break;
            }catch (NumberFormatException e){
                System.out.println("请输入的不是整数请重新输入:");
            }
        }
    }
}
  • 运行结果

在这里插入图片描述

4.2、throws - 默认
  • 含义:将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM,JVM输出异常信息之后退出程序;

    • 1、如果一个方法(中的语句)可能生成某种异常,但是并不确定如何处理这些异常,则此方法应显示声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理
    • 2、在方法生命中throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
  • 特点:

    • ①使用throws,抛出异常,让调用f2方法的调用者处理
    • ②throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
    • ③throws关键字后也可以是 异常列表,即可抛出多个异常;
  • 范例

public class ExceptionSource {
    public static void main(String[] args) {
        f2();
    }
    public static void f2() throws ArithmeticException{
        int n1 = 10;
        int n2 = 0;
        double res = n1/n2;
    }
}
  • 运行结果:f2的异常在被调用时传递给JVM被处理

在这里插入图片描述

  • throws异常处理细节
    • 对于编译异常,程序中必须处理,比如try-catch 或 throws;
    • 对于运行异常,程序中如果没有处理,默认就是throws的方式处理;
    • 子类重写父类方法时,对抛出异常的规定子类重写的方法所抛出的异常类型要么和父类抛出一致,要么为父类抛出的子类型
    • 在throws过程中,如果有方法try-catch,就相当于处理异常,就可以不必throws;
4.3、自定义异常
  • 自定义异常:自己设计异常类,用于描述该错误信息

  • 语法格式

public class XXException extends Exception|RuntimeException{
          添加一个空参数的构造方法
          添加一个带异常信息的构造方法
}
  • 范例
public class ExceptionSource {

    public static void main(String[] args) throws Exception {
        if((10+20)==30) {
            throw new AddException("错误的相加操作!不允许");		 }
    }}

class AddException extends Exception{
    public AddException(String msg) {
        super(msg);
    }
}
  • 运行结果

在这里插入图片描述

4.4、throw和throws的对比
名称意义位置后面跟的东西
throws异常处理的一种方式方法声明处异常类型
throw手动生成异常对象的关键字方法体中异常对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

随缘清风殇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值