(十六)异常
异常分类
Throwable
┃
┏━━━━━━━━┓
Error Exception
┃
┏━━━━━━━━┓
IOException RuntimeException
异常对象都派生于Throwable类的一个实例,即所有异常都是继承Throwable类。
异常分为两种:
(1)Error类,描述java系统内部错误,不需开发人员关注。
(2)Exception,分为RuntimeException和其他异常(如IOException)
RuntimeException:程序错误导致的异常
如:错误类型转换,数组访问越界,访问空指针
其他异常:程序本身没问题,但由于像I/O错误这类问题导致的异常。
如:试图在文件尾部后面读数据,打开不存在的文件,根据字符串查找Class对象而字符串指定的类不存在。
声明已检查异常
方法应该在首部声明所有可能抛出的异常。在自己编写方法时,不可能所有抛出的异常都声明。
至于什么时候用throws声明异常,记住遇到以下4中情况应该抛出异常:
- 调用一个抛出已检查异常的方法,如FileInputStream构造器
- 程序运行时发现错误,并且利用throw语句抛出一个已检查异常
- 程序错误,如数组访问越界
- Java虚拟机和运行库的内部错误
如果出现前两种情况,则必须告诉调用该方法的程序员有可能抛出异常。
第三种属于RuntimeException,我们不应该抛出这类异常,因为这属于程序错误,应该尽量修复这类程序错误,而不是抛出异常。
第四种属于Error,开发人员不需要声明这类错误,因为任何代码都有抛出这类异常的能力。
注:如果子类覆盖了超类的方法,子类中声明的异常不能比超类方法声明的异常更通用。超类方法未声明异常,则子类对应方法也不应该声明。
创建异常类
所有异常都继承Throwable类,所以自定义异常可以继承于它,当然一帮也可以继承于它的子类Exception。
异常发生后打印信息,在构造器中初始化。构造器调用超类构造器初始化。
import java.io.IOException; public class MyException extends Exception { public MyException(){} public MyException(String msg){ super(msg);//产生异常后,传入的信息 } }
public class Main { public static void main(String[] args)throws MyException{ throw new MyException("抛出一个自定义异常!"); } } 输出: Exception in thread "main" project03.MyException: 抛出一个自定义异常! at project03.Main.main(Main.java:5)
捕获异常
遇到异常,处理抛出而不管他外,我们还可以使用try-catch语句捕获它并进行处理。
public class Main { public static void main(String[] args){ try { test(); } catch (MyException e) { System.out.println("执行test()时,捕捉到一个异常!\n内如如下:"); e.printStackTrace(); } } public static void test()throws MyException{ throw new MyException("抛出一个自定义异常!"); } } 执行test()时,捕捉到一个异常! 内如如下: project03.MyException: 抛出一个自定义异常! at project03.Main.test(Main.java:14) at project03.Main.main(Main.java:6)
注:如果编写一个覆盖超类的方法,超类的方法没有抛出异常,那这个方法也不能抛出异常,必须捕获所有异常。