开发喵星球

异常的梳理和总结

pPeHkB4.png pPeHp90.png

本文内容是对异常的梳理和总结,本文内容包括:

为什么使用异常

异常体系结构

image-20230831140629797

异常体系结构的四个重要的类

异常两个重要的方法

异常和错误的区别

编译时异常和运行时异常

处理异常的方式

异常处理有三种方式(第二种和第三种本质上是同一种)

  1. try catch finally:==用于被调方法自己处理异常==

    形式一:try -catch

    public void method(){
        try{
            // try 块中放可能抛出异常的代码 
        }catch(ArithmeticException e){
            // catch 块用于捕获异常,异常一旦被捕获,就相当于没有异常了,因此程序可以继续向后运行
        }
    }
    

    形式二:try -catch-finally

    public void method(){
        try{
            // try 块中放可能抛出异常的代码 
        }catch(ArithmeticException e){
            // catch 块用于捕获异常,异常一旦被捕获,就相当于没有异常了,因此程序可以继续向后运行
        }finally{
            // finally 编写释放资源的代码,finally块无论是否发生异常都要执行
        }
    }
    

    形式三:多重catch,try -catch-catch

    public void method(){
        try{
            
        }catch(ArithmeticException e){// 多个catch 块时子类写在前面 
            
        }catch(ArithmeticException e){// 多个catch 块时父类写在后面 
           
        }
    }
    

    形式四:try – finally

    public void method(){
        try{
            // try 块中放可能抛出异常的代码 
        }finally{
            // finally 编写释放资源的代码,finally块无论是否发生异常都要执行
        }
    }
    
  2. throw throws:==用于异常抛给主调方法处理==

    • throws写在方法声明后面,告诉主调方法,当前被调方法可能抛出的异常
    • 若抛出运行时异常,主调方法可处理也可不处理。
    // throws声明当前方法可能抛出RuntimeException,主调方法可处理也可不处理
    public void setAge(int age) throws RuntimeException{
        if(age<0){
            throw new RuntimeException("年龄小于0");// throw抛出异常
        }
        this.age = age;
    }
    public void method(){
        setAge(-1); //主调方法未处理运行时异常
    }
    
    • 若抛出编译时异常,主调方法必须处理。
    // throws声明当前方法可能抛出Exception,主调方法必须处理
    public void setAge(int age) throws Exception{
        if(age<0){
            throw new Exception("年龄小于0");// throw抛出异常
        }
        this.age = age;
    }
    public void method(){
        try{
            setAge(-1);
        }catch(Exception e){ //主调方法必须处理编译时异常
            e.printStackTrace();
        }
    }
    
  3. try with resource:==用于确保释放资源,就是调用close()方法==(当try块执行结束后就会调用try()括号中对象的close()方法来确保关闭资源)

    • try with resource代码示例
    public static void main(String[] args) {
        // try块执行结束后,自动调用scanner对象的close()方法,确保关闭scanner对象,释放资源,也就是释放内存
        try(Scanner scanner = new Scanner(System.in)){
            String name = scanner.next();
            System.out.println(name);
        }
    }
    
    • 上面源码对应的字节码如下
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
    
        try {
            String name = scanner.next();
            System.out.println(name);
        } catch (Throwable var5) {
            try {
                scanner.close();
            } catch (Throwable var4) {
                var5.addSuppressed(var4);
            }
    
            throw var5;
        }
    
        scanner.close();
    }
    
    • 观察字节码,发现是不是scanner对象调用了close()方法,释放了内存

自定义异常

为什么要自定义异常:

自定义异常步骤:

自定义异常示例:

// 自定义异常
class MyException extends Exception{
    public MyException(String message){
        // 通过构造函数将异常描述信息传递给异常父类
        super(message);
    }
}
public class UserController {
    public static void main(String[] args) throws MyException {
        int i=1 ,j = 0;
        if(j ==0){
            // 将自定义异常抛给虚拟机,让虚拟机去处理
            throw new MyException("除数不能为0");
        }
        System.out.println("i / j = "+ i/j);
    }
}

运行结果

image-20230830163614411

抛异常结束方法运行

方法结束运行的三种情况

public void method(){
    int i = 1/0; //抛出除零异常,方法停止运行
    这里的代码没有机会执行
}
public void method(){
    some code
    throw new RuntimeException("抛出异常");//抛出除零异常,方法停止运行
    这里的代码没有机会执行
}
   
分类:Java/OOP 作者:开发喵 发表于:2023-09-05 17:36:51 阅读量:116
<<   >>


powered by kaifamiao