异常的概念与分类 异常处理 创造自己的异常 断言 Jdk7.0的新特性 日志 总结
一、异常概念与分类
try/catch
异常分类
异常是继承自Throwable类的对象,所有Throwable类的子孙类所产生的对象都是例外
Error:
Java虚拟机生成并抛出,Java程序不做处理.
RuntimeException(被0除等系统错误,数组下标超范围):不需要 throw和声明
系统检测, 用户Java 程序可不做处理,系统将它们交给缺省的异常处理程序
Run-time Exception系统抛出但没有捕获导致程序终止,并调用printStackTrace()打印异常位置
Exception(程序问题,可预知):
Java编译器要求Java程序必须捕获或声明所有的非运行时异常 throw:用户自己产生异常
异常分类-CheckedException——可检测/捕获型,除Error或RuntimeException及它们子类以外类型的所有异常
如果一个方法导致受检异常但不处理,要求在方法声明中包含 throws 子句,通知潜在调用者。 一个throws子句列举了一个方法可能引发的所有受检异常类型
编译期异常,一般开发过程会针对系统进行CheckedException的设计
在使用能够产生异常的方法而没有捕获和处理,将不能通过编译
二、异常处理——返回安全状态并允许用户执行其他命令
*:回避异常,异常将在调用堆栈中向下传递,直到被处理
异常处理模型——5个关键字 try、catch、throw异常抛出、throws、finally
自行处理 | 回避异常 |
可能引发异常的语句封入try块,处理异常语句封入catch块 | 在方法声明中包含 throws 子句,通知潜在调用者,如果发生异常,必须由调用者处理 |
Java程序方法产生错误,该方法创造一个异常对象并将其交给运行系统,运行系统从错误发生处开始寻找处理错误的程序段,捕获异常过程可以沿方法调用的逆向顺序寻找
try | catch | finally |
throw关键字出现在函数体内部,程序会在throw语句后立即终止执行,位于throw语句之后的语句块不会执行
多个 catch 块
catch语句块所捕获的受检异常,必须是try语句块中可能出现的受检异常,否则编译出错。 具有父子关系的异常,必须先处理子异常。没有父子关系的处理顺序任意。
嵌套try-catch块——块一部分引起错误,而整个块可能引起另一个错误
使用嵌套try块时,先执行内部 try 块,若没有遇到匹配的 catch 块,将检查外部 try 块的catch块
throw抛出异常——throw语句操作数是Throwable类类型或Throwable子类类型的一个对象
finally 块——无论是否出现异常,finally块都将运行
确保在出现异常时所有清除工作都将处理,与 try 块一起使用
try或catch遇到return,先转向finally,执行finally语句
finally也遇到return则执行finally的return,否则执行完finally后执行转入finally之前在try或catch块中遇到的return. 均未遇到return在finally之后程序仍继续执行
try、catch、finally变量作用域为代码块内部 | ||
try、catch(一或多个)、finally(最多一个)均不能单独使用 | ||
多catch只匹配一个异常类,匹配顺序由上到下,声明过程中子类放在前边捕捉 | ||
try+catch | try+catch+finally | try+finally |
异常抛出
一个方法中抛出异常,同时捕捉
多个方法调用时,特定(适当)的方法捕捉异常
被调用的方法主动抛出异常(throws)
import java.io.IOException;
// 导入IOException类,处理可能发生的I/O异常
class Test {
// 定义静态方法getChar抛出IOException
static char getChar() throws IOException {
char c = (char) System.in.read();
// 从标准输入读取一个字节并转换为char类型
return c;
}
public static void main(String args[]) {
try {
char c = getChar(); // 调用getChar方法并保存返回的字符
System.out.println(c);
} catch (IOException e) {
System.out.println(e);
}
}
}
等待用户在控制台输入一个字符。用户输入字符并按下回车键后:
System.in.read() 读取用户输入的字符。在控制台中,每次按键都会读取一个字符,按下回车键时,实际上会读取两次:一次是实际的字符,另一次是回车符(换行符)
read()方法返回字节(int类型),所以需要强制转换为char类型。ASCII字符可以直接强制从字节转换为字符
读取过程中发生任何I/O异常(e.g:输入/输出流被关闭),捕获IOException
程序只会读取并打印第一个输入的字符,然后立即退出
主动抛出异常
void parseObj(String s) throws NullPointerException {
if (s == null)
throw new NullPointerException();
… …;
}
遇到throw后,该过程会返回。<=>在该处遇到了异常。如果外部有try语句,则进入catch,如果catch不能处理,或没有try则相当于return,后面语句不会执行.
三、自定义异常
创造自己的异常——用户自己定义,不是系统监测到的异常(下标越界,被0-除)——throw new MyException()
同样用try--catch捕获,但必须由用户自己抛出
异常是一个类,用户定义的异常必须继承自Throwable或Exception类或其他Exception子类,建议用Exception类
继承RuntimeException或其子类,自定义类为unchecked exception |
继承Exception,该类为checked exception |
RuntimeException——虚拟机,其他受检异常——代码
Exception 类继承 Throwable
String getMessage(); | String toString(); |
void printStackTrace(); | Throwable fillInStackTrace(); |
创建异常
自定义异常类必须是java.lang.Exception或者Throwable类的子类
Exception() Constructs a new exception with null as its detail message. | Exception(String message) Constructs a new exception with the specified detail message. |
可以不定义构造方法 SimpleException() { super(); } 定义自已的构造方法 |
深入了解Throwable类——所有错误(Error)或异常(Exception)的超类
线程创建的时候执行堆栈的快照 |
有关错误的消息字符串,比如该异常出现位置以及代码里的哪一行 |
指出异常的原因:该异常是由哪个异常导致或由哪个异常抛出的Throwable导致这个Throwable的产生 |
六、日志处理——必须捕获引发的每个异常,否则应用程序不会正常中止
异常处理允许在一个地方集中进行错误处理->创建功能强大且健壮的代码。
异常处理辅助进行调试及维护工作并提高系统容错性和稳定性
关键字 throws 用于列出一个方法可能引发的异常类型
不管是否发生异常,都将执行 finally