异常
异常对象都是派生于Throwable类的一个实例。
Error类层次描述了Java运行时系统的内部错误与资源耗尽错误,如果出现这样的错误,应使程序安全的终止之外,无其他办法,很少出现。
需要关注的是Exception层次结构,含两个分支:RuntimeException和其他异常。由程序错误导致的异常属于RuntimeException,而程序本身没问题,但由于像I/O错误的属于其他异常。
派生于RuntimeException的异常包含下面几种情况:
1.错误类型转换。
2.数组访问越界。
3.访问null指针。
出现其他异常的情况包括:
1.试图在文件尾部后面读取数据。
2.试图打开一个不存在的文件。
3.试图根据给定的字符串查找Class对象,而这个类表示的类并不存在。
如果出现RuntimeException异常,就一定是你的问题,相当有道理的规则
Java语言将派生于Error类或者RuntimeException类的所有异常称为非受查异常,所有其他异常称为受查异常,编译器将核查是否为所有的受查提供了异常处理器。
声明受查异常
public FileInputStream(String name) throws FileNotFoundException
构造器会根据给定的String参数产生一个FileInputStream对象,但也有可能抛出FileNotFoundException异常。如果抛出异常则不会初始化对象。
编写方法时,不必将所有可能抛出的异常都进行声明,什么异常必须使用throws子句声明,以下4种情况:
1.调用一个受查异常的方法,如 FileInputStream 构造器。
2.程序运行时发现错误,并且利用 throw 语句抛出一个受查异常。
3.程序出现错误,如 a[-1] 会抛出一个 ArrayIndexOutOfBoundException 这样的非受查异常。
4.Java虚拟机和运行时哭出现的内部错误。
不需要声明Java内部错误,即从Error继承的错误,我们对其没有控制能力。
同样也不应该声明从RuntimeException继承的那些非受查异常。如数组越界什么的,应该花时间在修复程序错误上,而不是说明这些错误发生的可能性。
总之一个方法必须声明抛出所有的受查异常,而非受查异常要么无法控制(Error),要么避免发生(RuntimeException)。如果方法没有声明所有可能发生的受查异常,编译器会发出一个错误信息。
创建异常类
在程序中,可能会遇到任何标准异常类都无法充分描述清楚的问题,所有可以直接创建一个异常类,定义一个派生于Exception的类,或者Exception子类的类,例如定义一个派生于IOException的类,应该包含俩个构造器,一个是默认的,另一个是带有详细信息的构造器(超类中Throwable的toString方法将会打印这些信息,在调试中非常有用)。
class FileFormatException extends IOException{
//默认构造器
public FileFormatException(){}
public FileFormatException(String gripe){
super(gripe);
}
}
//抛出
String 类名(...) throws FileFormatException{
...
}
举个例子
//自定义一个异常
public class AgeException extends Exception{
public AgeException(){
super("年龄不合法");
}
}
public class Person{
.....
public void setAge(int age){
if(age<0 || age>150){
try{
throw new AgeException(); //使用自定义的异常
}catch(AgeException e){
e.printStackTrace();
System.out.println(e.getMessage());
}
}else
this.age=age;
}
}
RuntimeException的API
RuntimeException()
构造一个新的运行时异常,以 null作为其详细信息。
RuntimeException(String message)
使用指定的详细消息构造新的运行时异常。
RuntimeException(String message, Throwable cause)
构造一个新的运行时异常与指定的详细信息和原因。
RuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
构造一个新的运行时异常,其中包含指定的详细消息,启用或禁用抑制,启用或禁用可写栈跟踪。
RuntimeException(Throwable cause)
构造具有指定的原因和 (cause==null ? null : cause.toString())详细消息(它通常包含的 cause类和详细信息)的新的运行时异常。
IOException的API
IOException()
构造一个 IOException与 null作为其错误详细信息。
IOException(String message)
构造一个 IOException带指定详细信息。
IOException(String message, Throwable cause)
构造一个 IOException带指定详细消息和原因。
IOException(Throwable cause)
构造一个 IOException与指定的原因和详细消息 (cause==null ? null : cause.toString()) (它通常包含的类和详细消息 cause )。
我们来看下
getMessage:返回详细信息
getCause:返回原因
public class Test {
public static void main(String[] args) {
int []a =new int[3];
try {
System.out.println(a[4]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("异常信息:"+e.getMessage());
System.out.println("异常原因:"+e.getCause());
}
}
}
//输出
异常信息:4
异常原因:null