秦疆的Java课程笔记:78 异常 捕获和抛出异常

发布时间 2023-12-19 17:49:56作者: Acolyte_9527
  • 异常处理五个关键词:trycatchfinallythrowthrows

  • 写一个会出错的代码:

public class Test1 {  
    public static void main(String[] args) {  
        int a = 1;  
        int b = 0;  
        System.out.println(a/b);  
    }  
}
====运行报错====
Exception in thread "main" java.lang.ArithmeticException: / by zero
  • 加上异常处理机制:
public class Test1 {  
    public static void main(String[] args) {  
        int a = 1;  
        int b = 0;  
        try {   //`try`监控区域
            System.out.println(a/b);  
        } catch(ArithmeticException e) {   //`catch`捕获异常
            System.out.println("异常:除数不得为0!");  
        } finally {   //`finally`处理善后工作
            System.out.println("finally");  
        }  
    }  
}
====运行结果====
异常:除数不得为0!
finally
  • finally语句不是必须的,之后学习I0流、资源等相关内容,需要一些关闭操作,可以写在fianlly语句中。
  • 将上面的演示修改一下,用一个循环调用,代替除以0错误。
public class Test2 {  
    public static void main(String[] args) {  
        try {  
            new Test().a();  
        } catch(ArithmeticException e) {  //捕获异常的类型是错误的
            System.out.println("出错了!");  
        } finally {  
            System.out.println("finally");  
        }  
    }  
    public void a() {b();}  
    public void b() {a();}  
}
====运行结果====
finally   //未能捕获异常,但是finally依旧被执行了
Exception in thread "main" java.lang.StackOverflowError   //报Error
  • 将上述代码中catch()语句改为catch(Throwable e),之前说过Throwable是所有异常和错误的基部类,可以捕获所有异常。
public class Test2 {  
    public static void main(String[] args) {  
        try {  
            new Test().a();  
        } catch(Throwable e) {  
            System.out.println("出错了!");  
        } finally {  
            System.out.println("finally");  
        }  
    }  
    public void a() {b();}  
    public void b() {a();}  
}
====运行结果====
出错了!   //成功捕获
finally
  • try…catch语句是可以像if…else语句的格式一样,捕获多个可能的异常,试试从子类到父类的异常捕获:
public class Test3 {  
    public static void main(String[] args) {  
        int a = 1;  
        int b = 0;  
        try {  
            System.out.println(a/b);  
        } catch(ArithmeticException e) {  
            System.out.println("ArithmeticException");  
        } catch(Exception e) {  
            System.out.println("Exception");  
        } catch(Throwable e) {  
            System.out.println("Throwable");  
        } finally {  
            System.out.println("finally");  
        }  
    }  
}
====运行结果====
ArithmeticException
finally
  • 若需要捕获多个异常,则需要从小到大去捕获。

  • 如果将父类异常写在子类异常的前面,那么IDEA里子类异常的语句就会报错:已捕捉到异常。

  • IDEA中,选中需要捕捉异常的代码块(比如上述例子中的System.out.println(a/b);),使用快捷键Ctrl+Alt+T,在弹出的“包围方式”菜单中,(通常情况)选择try/catch/finally,则会自动生成异常捕获语句。(这里生成的语句,JDK21和JDK8不太一样。)

  • 主动抛出异常:throwthrows,一般用在方法中。

public class Test4 {  
    public static void main(String[] args) {  
        new Test4().test(1,0);  
    }  
    public void test(int a,int b) {  
        if (b==0) {  
            throw new ArithmeticException();  
        }  
        System.out.println(a/b);  
    }  
}
  • 假设在方法中处理不了这个异常,就在方法上抛出异常。
public class Test5 {  
    public static void main(String[] args) {  
        try {  
            new Test5().test(1,0);  
        } catch (ArithmeticException e) {  
            throw new RuntimeException(e);  
        }  
    }  
    public void test(int a,int b) throws ArithmeticException {  
        if (b==0) {  
            throw new ArithmeticException();  
        }  
        System.out.println(a/b);  
    }  
}
  • 按照秦疆老师的说法,这样的处理方法在抛出异常的同时不妨碍程序继续执行,但是没有做具体演示,上述代码可能并不是一个理想案例,我暂时也不知道该怎么演示throws的功能。