跟着大佬学java第九课,异常处理

本文详细探讨了Java中的异常处理机制,包括什么是异常,其分类,常见错误与异常的区别,以及try-catch-finally、自定义异常的使用。通过实例展示了如何捕获、抛出和处理异常,以确保程序的健壮性与错误处理能力。
摘要由CSDN通过智能技术生成

异常处理详解

什么是异常

实际工作中,遇到的情况不可能是非常完美的。用户输入不符合要求、打开的文件不存在、数据获取为空、内存或硬盘满了

软件程序运行过程中,非常可能遇到这些异常问题,我们叫异常(Exception)

异常指程序运行中出现的不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等

异常发生在程序运行期间,它影响了正常的程序执行流程

简单分类

检查性异常:用户错误或问题引起的异常,是程序员无法预见的

运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略

错误ERROR:错误不是异常,而是脱离程序员控制的问题,错误在代码中通常被忽略。例如:栈溢出,错误就发生了,编译时检查不到

异常/错误样例

//1. a调用b,b调用a,循环嵌套导致的错误
public class Demo01 {
    public static void main(String[] args) {
        new Demo01().a();
    }
    public void a(){
        b();
    }
    public void b(){
        a();
    }
}
//Exception in thread "main" java.lang.StackOverflowError

//2. 除数为零导致的异常
public class Demo01 {
    public static void main(String[] args) {
        System.out.println(11/0);
    }
}
//Exception in thread "main" java.lang.ArithmeticException: / by zero

//3. 程序结束缺少分号,程序检测就会报错,运行报错
public class Demo01 {
    public static void main(String[] args) {
        System.out.println()
    }
}
//java: 需要';'

异常体系结构

异常处理框架

  1. java把异常当对象处理,并定义一个基类(java.lang.Throwable)作为所有异常的超类。

  2. 在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception

  3. Throwable 异常体系

    1. Error 错误
      1. VirtulMachineError(虚拟机异常)
        1. StackOverFlowError
        2. OutOfMemoryError
      2. AWTError(GUI异常)
    2. Exception 异常
      1. IOEception
        1. EOFException
        2. FileNotFoundException
      2. RuntimeException
        1. ArrithmeticException
        2. MissingResoureeException
        3. ClassNotFoundException
        4. NullPointerException
        5. IllegalArgumentException
        6. ArrayIndexOutOfBoundsException
        7. UnkownTypeException

Error

  1. Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关
  2. Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需要的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;
  3. 还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为他们在应用程序的控制和处理能力之外,并且绝大多数是程序运行时不允许出现的状况。

Exception

  1. 在Exception分支中有一个重要的子类RunTimeException(运行时异常)

    1. ArrayIndexOutOfBoundException(数组下表越界)
    2. NullPointerException(空指针异常)
    3. ArithmeticException(算术异常)
    4. MissingResourceException(丢失资源)
    5. ClassNotFoundException(找不到类)

    等异常,这些异常时不检查异常,程序中可以选择捕获处理,也可以不处理

  2. 这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生

  3. Error和Exception的区别:

    Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常

异常处理机制

关键字:try–尝试处理、catch–捕获、finally–之后执行、throw–方法内主动抛出异常、throws–向上抛出异常

抛出异常

主动抛出异常,一般用在方法中使用

public class Test2 {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        new Test2().ari(a,b);
    }
    
    public void ari(int a, int b){
        if (b==0){
            throw new ArithmeticException();        //针对可能出错的地方,主动抛出异常,一般在方法中使用
        }
        //System.out.println(a / b);
    }
}
//使用 throw ,即使程序没有a/b ,也能获取到异常并抛出
public class Test2 {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        try {
            new Test2().ari(a,b);
        } catch (ArithmeticException e) {
            //在catch中处理异常e
            e.printStackTrace();
        }
    }

    //假设这个方法中,处理不了这个异常。从方法往上抛出
    public void ari(int a, int b) throws ArithmeticException{
        if (b==0){
            throw new ArithmeticException();        //针对可能出错的地方,主动抛出异常,
        }
        System.out.println(a / b);
    }
}

捕获异常

异常处理实例

捕获异常

//catch中捕获算术异常,其他异常无法捕获
public class Test {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        //可以没有finally,但必须要有try和catch,IO流,资源等需要关闭,关闭放在finally中
        //try内监控区域
        try {
            System.out.println(a/b);        //直接运行报错
        }
        //捕获到异常时运行
        catch (ArithmeticException e){		//捕获算术异常
            System.out.println("程序出现异常");
        }
        //继续执行,不论有没有捕获到异常
        finally {
            System.out.println("finally");
        }
    }
}
//catch中捕获异常,使用Throwable类,可以捕获类里面的所有子类
public class Test {
    public static void main(String[] args) {

        try {
            new Test().a();		//直接执行报错:StackOverflowError
        }catch (Throwable e){	//catch(想要捕获的异常类型)
            System.out.println("程序出现异常");
        }finally {
            System.out.println("finally");
        }
    }
    public void a(){ b(); }
    public void b(){ a(); }
}

catch异常捕获可以嵌套(捕获多个异常,类似 if( ) ),多层嵌套时,需要注意异常的范围,先判断小范围异常,若不满足则会执行下一个catch,且下一个catch捕获范围要大于上一个:

例:

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

        try {
            new Test().a();
        } catch(ArithmeticException a){
            System.out.println("算术异常");
        } catch (StackOverflowError s) {
            System.out.println("堆栈溢出异常");
        } catch (Throwable e){
            System.out.println("Throwable类捕获异常");
        }
        //继续执行,不论有没有捕获到异常
        finally {
            System.out.println("finally");
        }
    }
    public void a(){ b(); }
    public void b(){ a(); }
}

执行顺序:
    先判断是否为ArithmeticException,不是则继续往下执行
    判断是否为StackOverflowError,异常类型对应则下方异常捕获Throwable不再执行

结果:
    堆栈溢出异常
	finally

idea自动生成 try catch finally 快捷键:选中代码后,Ctrl + Alt + T

自动生成的catche{ }里的内容:printStackTrace();打印错误的栈信息,就是程序报错信息,可以修改或在前面添加代码手动结束程序–System.exit(0);

try catch 用处

不使用try catch ,在程序运行到此处出现异常,程序终止,无法向下执行

使用 try catch ,在程序捕获到异常以后,可以继续向下执行

自定义异常

  1. 使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可
  2. 在程序中使用自定义异常类,大体可分为以下几个步骤:
    1. 创建自定义异常类
    2. 在方法中通过throw关键字抛出异常对象
    3. 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作
    4. 再出现异常方法的调用者汇总捕获并处理异常

自定义异常实例

//自定义的异常类
public class MyException extends Exception{
    //传递数字>10
    private int detail;

    public MyException(int a) {
        this.detail = a;
    }

    //toString:异常的打印信息
    @Override
    public String toString() {
        return "MyException{" +
                "detail=" + detail +
                '}';
    }
}
//调用自定义的异常
public class Test {

    //可能存在异常的方法
    static void test(int a) throws MyException{//向上抛出异常
        System.out.println("传递的参数为:"+ a);
        if (a>10){
            throw new MyException(a);   //抛出异常
        }
        System.out.println("OK");
    }

    public static void main(String[] args) {
        try {
            test(11);		//抛出的异常由try-catch捕获
        } catch (MyException e) {
            System.out.println("MyException=>"+e);
        }
    }
}
结果:
    传递的参数为:11
	MyException=>MyException{detail=11}

实际应用中的经验总结

  1. 处理运行时异常时,此阿勇逻辑去合理规避同时辅助try-catch处理
  2. 在多重catch块后面,可以加一个catch (Exception) 来处理可能会被遗漏的异常
  3. 对于不确定的代码,也可以加上try-catch,处理潜在的异常
  4. 尽量去处理异常,切忌只是简单地调用 printStackTrace()去打印输出
  5. 具体如何处理异常,要根据不同的业务需求和异常类型去决定
  6. 尽量添加finally语句块去释放占用的资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值