9、异常
1. 什么是异常
异常指程序运行中出现的不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等,它影响了正常的程序执行流程。
异常类型:
-
检查性异常
最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。
-
运行时异常
运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
-
错误
错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。
异常体系结构:
所有的异常类是从 java.lang.Exception 类继承的子类。
Exception 类是 Throwable 类的子类。除了 Exception 类外,Throwable 还有一个子类 Error。
-
Error
- Error 类对象由 JVM 生成并抛出,大多数错误与代码编写者所执行的操作无关。
- 错误一般发生在严重故障时,它们在 Java 程序处理的范畴之外。
-
Exception
在 Exception 分支中有一个重要的子类 RuntimeException(运行时异常),这类异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
Error 和 Exception 的区别:
-
Error 通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,JVM 一般会选择终止线程;
-
Exception 通常情况下是可以被程序处理的,并且在程序中应该尽可能的去外理这些呈常。
2. 异常处理机制
捕获异常
使用 try 和 catch 关键字可以捕获异常。
try/catch
代码块放在异常可能发生的地方。try/catch
代码块中的代码称为保护代码。
使用 try/catch 的语法如下:
1 | try { |
finally
关键字用来创建在 try 代码块后面执行的代码块。
-
无论是否发生异常,finally 代码块中的代码总会被执行。
-
在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
finally 代码块出现在 catch 代码块最后,语法如下:
1 | try { |
不要在 finally
块中使用 return
原因:try 块中的 return 语句执行成功后,并不马上返回,而是继续执行 finally 块中的语句,如果此处存在 return 语句,则会在此直接返回,无情丢弃掉 try 块中的返回点。
注意事项:
- catch 不能独立于 try 存在
- 在 try/catch 后面添加 finally 块并非强制性要求
- try 代码后不能既没 catch 块也没 finally 块
- try, catch, finally 块之间不能添加任何代码
抛出异常
在 Java 中, throw 和 throws 关键字是用于处理异常的。
- throw 关键字用于在代码中抛出异常
- throws 关键字用于在方法声明中指定可能会抛出的异常类型
3. 自定义异常
使用 Java 内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。
一个异常类和其它任何类一样,包含有变量和方法。
在程序中使用自定义异常类,大体可分为以下几个步骤:
- 创建自定义异常类
- 在方法中通过 throw 关键字抛出异常对象
- 如果在当前抛出异常的方法中处理异常,可以使用
try/catch
语句捕获并处理;否则在方法的声明处通过 throws 关键字指明要抛出给方法调用者的异常,继续进行下一步操作 - 在出现异常方法的调用者中捕获并处理异常
注意事项:
- 所有异常都必须是 Throwable 的子类
- 如果希望写一个检查性异常类,则需要继承 Exception 类
- 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。