文章目录
异常
异常类的层次结构
Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误。程序不应该抛出这种类型的对象。
异常的分类
第一类:由编程错误导致的异常——RuntimeException(运行时异常)
- 错误的强制类型转换
- 数组访问越界
- 访问null指针
…
第二类:其他异常(编译时异常)——必须在编写程序时预先对这种异常进行处理
- 试图超越文件末尾继续读取数据
- 试图打开一个不存在的文件
- 试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在。
…
Java将派生于Error类或者RuntimeException类的所有异常成为非检查型(unchecked)异常,所有其他的异常称为检查型(checked)异常。
异常的处理
1、throws关键字
在方法的名称后用throws关键字声明,将异常抛出。方法的调用者仍要对该异常进行处理,可以抛出也可以使用try/catch进行捕捉。出现异常后,程序就会终止,后面的语句无法继续执行。
2、try/catch语句
在可能会发生异常的方法处用try/catch语句将其包裹起来,try语句块中写方法的调用,catch语句块对异常进行处理。捕捉到异常后,try/catch语句块后的语句仍然可以继续执行。
如何选择
选择的依据: 是否希望调用者对异常进行处理
如果希望让调用者知道可能会发生什么样的异常,想让调用者自己来处理一下,则使用throws关键字进行异常的处理,其他情况使用try/catch。
异常的方法(常用)
1、getMassage()
获取异常的描述信息
public class ExceptionMethodTest(){
public static void main(String[] args){
NullPointerException e = new NullPointerException("空指针异常");
String msg = e.getMessage();
System.out.println(msg);
//输出结果:
// 空指针异常
}
}
2、printStackTrace()
打印异常追踪的堆栈信息
public class ExceptionMethodTest{
public static void main(String[] args){
NullPointerException e = new NullPointerException("空指针异常");
e.printStackTrace();
//输出结果:
// java.lang.NullPointerException: 空指针异常
// at ExceptionMethodTest.main(ExceptionMethodTest.java:3)
}
}
异常的检查
import java.io.FileNotFoundException;
import java.io.FileInputStream;
public class ExceptionTest{
public static void main(String[] args) {
try{
method1();
} catch(FileNotFoundException e){
e.printStackTrace();
}
}
static void method1() throws FileNotFoundException {
method2();
}
static void method2() throws FileNotFoundException {
method3();
}
static void method3() throws FileNotFoundException {
FileInputStream e = new FileInputStream("E:\\不存在的路径");
}
}
运行结果:
java.io.FileNotFoundException: E:\不存在的路径 (系统找不到指定的文件。)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:212)
at java.base/java.io.FileInputStream.(FileInputStream.java:154)
at java.base/java.io.FileInputStream.(FileInputStream.java:109)
at ExceptionMethodTest.method3(ExceptionMethodTest.java:23)
at ExceptionMethodTest.method2(ExceptionMethodTest.java:19)
at ExceptionMethodTest.method1(ExceptionMethodTest.java:15)
at ExceptionMethodTest.main(ExceptionMethodTest.java:7)
查看打印的堆栈异常信息时,略过sun公司写好的java包中的异常语句后,从上往下一行一行检查程序出现的错误。
/*
at ExceptionMethodTest.method3(ExceptionMethodTest.java:23) 表示程序的第23行出现错误并且是问题的根源
at ExceptionMethodTest.method2(ExceptionMethodTest.java:19)
at ExceptionMethodTest.method1(ExceptionMethodTest.java:15)
at ExceptionMethodTest.main(ExceptionMethodTest.java:7)
*/
finally关键字
finally的使用
finally与try/catch语句一起使用,finally中的语句无论try语句块中是否出现异常都一定会执行。finally必须与try一起出现,不能单独编写。
public class FinallyTest{
public static void main(String[] args){
try{
System.out.println("try");
return;
} finally {
System.out.println("finally");
}
}
}
//输出结果:
// try
// finally
无法到达的语句:(Unreachable statement)
因为在try语句块中执行完retrun 程序就会结束,最后一行语句不会被执行。
public class FinallyTest{
public static void main(String[] args){
try{
System.out.println("try");
return;
} finally {
System.out.println("finally");
}
System.out.println("无法到达的语句"); //编写时报错 Unreachable statement
}
}
不会执行的finally
当显式的退出JVM时,其后面的finally语句就不会执行了。
public class FinallyTest{
public static void main(String[] args){
try{
System.out.println("try");
System.exit(0); //退出JVM
}finally{
System.out.println("finally"); //不会执行
}
}
}
final、finally、finalize的区别
final关键字修饰的类不能被继承,修饰的变量无法修改即为常量,修饰的方法为不可覆盖的方法。
finaly关键字使用在处理异常时,与try/catch一起使用。
finalize是Object类的一个方法名,由JVM的GC垃圾回收器负责调用。(已废弃)
自定义异常
有时在业务中异常并不能满足需求,则可以自定义异常。
自定义异常分为两步:
1、编写自定义异常类并继承Exception或者RuntimeException(取决于自定义的异常类型);
2、提供两个构造方法,一个无参,一个带有一个String参数。
//自定义异常
public class MyException extends Exception{
//无参构造方法
public MyException(){}
//带有一个String参数的构造方法
public MyException(String s){
super(s);
}
}