java虚拟机或java代码抛出(throw)的对象必须是throwable类或其子类的实例。同样,在catch语句中的只能是throwable类或其子类作为参数类型。Jdk中声明的可抛出对象包括Exception和Error,它们是throwable的子类。
Exception
Exception分为两种类型:Checked Exception和Runtime Exception。Checked Exception顾名思义是受检查的异常,在编译期,当代码调用一个抛出异常的方法时,必须声明该checked Exception。声明受检查异常的方式包括:
1.使用try..catch捕获;
2.使用throws 将异常抛出,交给上级类处理。
JDK中定义的Exception包括如下:
1.Checked Exception
- ClassNotFoundException
应用程序尝试使用forName方法、类加载的findSystemClass方法或loadClass方法,通过类名称去加载类时,若找不到该类就会抛出该异常。它是ReflectiveOperationException的子类。 - CloneNotSupportedException
类没有实现Cloneable接口,去调用父类(object)的clone方法时会抛出该异常。 - IllegalAccessException
应用程序通过反射实例化类、设置或修改字段、执行方法等时,但是没有相应权限时,就会抛出该异常,比如通过反射调用private修饰的方法,由于无法调用私有方法,那么就会抛出该异常。它是ReflectiveOperationException的子类。 - InstantiationException
应用程序通过newInstance方法创建类实例时,如果该类是抽象类、接口、私有类、或者没有默认构造函数等情况,那么就会抛出该异常。它是ReflectiveOperationException的子类。 InterruptedException
线程中断异常,当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常。有时候,一种方法可能希望测试当前线程是否已被中断,如果已被中断,则立即抛出此异常,例如下面代码:
if (Thread.interrupted()) // Clears interrupted status!
throw new InterruptedException();
当发生InterruptedException时,要么使用throws给父类,要么使用try..catch捕获,捕获到interruptedException时,一定要做一些处理,否则程序不知道线程已经发生过中断了。下面的一篇关于interruptException的博文写的挺好:
http://coolxing.iteye.com/blog/1474375NoSuchFieldException
字段找不到异常,它是ReflectiveOperationException的子类。- NoSuchMethodException
方法找不到异常,它是ReflectiveOperationException的子类。 - ReflectiveOperationException
表示在反射操作中,抛出的异常,以上ClassNotFoundException、IllegalAccessException、InstantiationException
、NoSuchFieldException和NoSuchMethodException均是该类的子类,在反射中的抛出的异常。
总得来说,jdk定义的受检查异常分为三大类:反射异常、线程中断异常、克隆不支持异常。
2.RuntimeException
运行时异常,是虚拟机(jvm)在正常运行时抛出的异常,是不受检查的异常,在代码中不需要声明运行时异常(使用try..catch或throws),也能抛出。运行时异常表明代码本身是有bug的,在编译期无法检查出,但是在运行期该bug就会暴露出。
- ArithmeticException
计算异常。 - ArrayIndexOutOfBoundsException
数组索引为负数或大于长度时,抛出该异常。它是IndexOutOfBoundsException的子类。 - ArrayStoreException
数组增加的元素类型与数组定义的类型不一致,抛出该异常。 - ClassCastException
类型转换异常。比如父类转子类就会报该异常。 - EnumConstantNotPresentException
枚举常量不存在异常。 - IllegalArgumentException
非法参数异常。 IllegalMonitorStateException
线程没有获取对象的锁,去执行wait或者notify等方法时就会抛出该异常。具体理解该异常,参考下面两个博文:
http://blog.csdn.net/spring123tt/article/details/6102613
http://www.importnew.com/16453.htmlIllegalStateException
方法调用不是正确的时机时会抛出该异常,比如在servlet中使用out.write()方法后,同时使用response.getOutputStream()时就会抛出该异常,因为servlet不允许这两种方法同时使用- IllegalThreadStateException
不是合适的时机对进程进行操作,比如线程执行了两次start方法,若线程在运行状态,则第二次执行start方法时就会报该异常。它是IllegalArgumentException的子类。 - IndexOutOfBoundsException
索引越界异常。 - NegativeArraySizeException
创建数组时,数组长度定义为负数时,抛出该异常。 - NullPointerException
空指针异常,调用空对象的方法、字段时会抛出该异常。 - NumberFormatException
把一个字符串转换为数值类型时,但是这个字符串的格式不是数值类型,就会抛出该异常。它是IllegalArgumentException的子类。 - RuntimeException
所有各种运行时异常的父类。 - SecurityException
安全异常,比如当程序要在某目录下创建文件时,但是操作系统不允许在该目录创建文件,就会抛出该异常。 - StringIndexOutBoundsException
对String的方法进行操作时抛出的异常,比如charAt()方法,当索引超出小于0,大于或等于字符串的长度时就会抛出该异常。它是IndexOutOfBoundsException的子类。 - TypeNotPresentException
类型不存在异常,通过反射读取注解时,会经常抛出该异常。 - UnsupportedOperationException
Java集合操作抛出的异常。
综合以上可知,运行时异常主要分为:计算异常、索引超标异常、类型转换异常、空指针异常、类型不存在异常、线程非法操作异常、不支持操作的异常等类型。
Error
Error是由虚拟机导致的问题,比如系统崩溃、内存不足、堆溢出等错误。Java编译器不会检查Error。Error导致的程序中断,紧靠程序本身无法恢复和语法,当然也会和程序有关系,但是应该让程序终止,找出错误原因。jdk中常见的错误如下:
- OutOfMemoryError
虚拟机无法为对象分配足够的空间或者垃圾收集器没有足够的内存使用,就会抛出该错误。当多线程并发时,容易造成抛出该错误。 - StackOverflowError
Java虚拟机中的栈存放的是方法、局部变量、对象引用等,当程序无限制使用递归,且方法中的变量无限制增大时,jvm无法分配更多的栈内存时,就会抛出该错误。 - UnknownError
虚拟机未知错误, - UnsatisfiedLinkError
使用jni调用本地方法,找不到该方法就会抛出异常。 - UnsupportedClassVersionError
这个错误一般是因为我们使用高版本的jdk编译的class文件,在低版本的jvm上运行造成的。 - VirtualMachineError
虚拟机被破坏或运行的资源不足,会抛出该错误。
throws与throw关键字
throws应用在方法层上,例如:
public void execute() throws SqlExctpion,NullPointerException{}
throw应用在语句层面上,例如:
public void execute(){
try{
throw new SqlException();//
}catch{}
}
简单的理解就是throws是抛出该方法的所有异常,交予父类处理;throw是抛出指定的异常,因为有些异常可能要在方法中捕获。