Java异常小结

本文深入探讨了Java异常层次结构、Throwable常用方法,以及try-catch-finally和try-with-resource的关键用法,包括检查异常处理、资源自动管理的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、异常的层次框架

在这里插入图片描述
Error往往是硬件异常,Exception是程序异常,其中分为检查异常和非检查异常,检查异常如果不被处理,无法通过编译,但是非检查异常不被处理也可以通过编译,更多是代码的逻辑错误。

二、Throwable常用的方法

  • String getMessage(): 返回异常发生时的简要描述
  • String toString(): 返回异常发生时的详细信息
  • String getLocalizedMessage(): 返回异常对象的本地化信息。使用 Throwable 的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与 getMessage()返回的结果相同
  • void printStackTrace(): 在控制台上打印 Throwable 对象封装的异常信息

三、异常的使用

对于检查性异常,有两种不同的处理方式:

  • 使用 「try…catch…finally…」 语句块处理
  • 在方法中使用 「throws/throw」 关键词将异常交给方法调用者去处理
    使用throw或throws关键字抛出异常,多个异常用逗号分隔

3.1 try-catch-finally关键字

把try/catch 代码块放在异常可能发生的地方。

try {
    ...
} catch (IOException ioException) {
    ...
} catch (Exception exception) {
    ...
} finally {
    ...
}

try块:

  • 如果执行完try且不发生异常,则接着去执行finally块中的代码和finally后面的代码(如果有的话)。
  • 如果程序发生异常,则尝试去匹配对应的catch块。

catch块:

  • 每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java7中可以将多个异常声明在一个catch中。
  • catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
  • 在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。
  • 如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个方法的外部调用者中去匹配异常处理器。
  • 如果try中没有发生异常,则所有的catch块将被忽略。

finally 块:

  • finally块不是必须的,通常是可选的。
  • 无论异常是否发生,异常是否匹配被处理,finally中的代码都会执行。
  • 一个try至少要有一个catch块,否则, 至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获和处理异常,处理异常的只能是catch块。
  • finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。
  • finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:「System.exit()」 。

注意:
(1)如果程序有return,则先执行完finally再执行return。
(2)catch的执行顺序是自上而下的,因此,应该先放子类的异常,再写父类的异常。
(3)资源要在finally中关闭
(4)不要在 finally 语句块中使用 return! 当 try 语句和 finally 语句中都有 return 语句时,try 语句块中的 return 语句不会被执行。

举例如下:

public class TestStream { 
    public static void main(String[] args) {
        File f = new File("d:/test.txt");
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(f); 
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 在finally 里关闭流
            if (null != fis)
                try { 
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        } 
    }
}

3.2 try-with-resource关键字

将资源定义在try里面,会自动释放资源。

举例如下:

public class TestStream {  
    public static void main(String[] args) {
        File f = new File("d:/lol.txt");
  
        //把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
        try (FileInputStream fis = new FileInputStream(f)) {
            byte[] all = new byte[(int) f.length()];
            fis.read(all);
            for (byte b : all) {
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }  
    }
}

声明多个资源,使用分号隔开

try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new File("test.txt")));
             BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) {
            int b;
            while ((b = bin.read()) != -1) {
                bout.write(b);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }

在 try-with-resources 语句中,任何 catch 或 finally 块在声明的资源关闭后运行

补充

java异常的最佳实践:
https://blog.youkuaiyun.com/hejjunlin/article/details/124829929

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值