原文地址:http://chenxiaoqiong.com/articles/tryCatch/
Throwable是所有异常的基类,程序中一般不会直接抛出Throwable对象。Exception和Error是Throwable的子类,Exception下面又有RuntimeException和一般的Exception两类。可以把JAVA异常分为三类:
检查性异常(非RuntimeException):所有继承自Exception并且不是RuntimeException的异常都是checked Exception。JAVA 语言规定必须对此类异常作处理,编译器会对此作检查,要么在方法体中声明抛出,要么使用catch语句捕获,不然不能通过编译。
运行时异常(RuntimeException):与检查性异常相反, 编译器不会检查程序是否对RuntimeException作了处理。RuntimeException发生的时候,表示程序中出现了编程错误,所以应该找出错误修改程序,而不是去简单的捕获或者抛出。
错误(Error): Error表示程序在运行期间出现了十分严重、不可恢复的错误,在这种情况下应用程序只能中止运行,例如JAVA 虚拟机出现错误。编译器不会检查Error是否被处理,在程序中不用捕获Error类型的异常;一般情况下,在程序中也不应该抛出Error类型的异常。
在Java中,异常通过try-catch语句捕获。其一般语法形式为:
try { // 可能会发生异常的程序代码 } catch (Type1 id1) { // 捕获并处理try抛出的异常类型Type1 } catch (Type2 id2) { // 捕获并处理try抛出的异常类型Type2 } finally { // 无论是否发生异常,都将执行的语句块 }try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。 catch 块:用于处理try捕获到的异常。 finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行: 1)在finally语句块中发生了异常。 2)在前面的代码中用了System.exit()退出程序。 3)程序所在的线程死亡。 4)关闭CPU。 执行过程:当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
throws关键字放在方法签名的尾部,一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。如果一个方法可能会出现异常,但没有能力处理这种异常,则在方法声明处用throws子句来声明抛出异常。语法格式:
methodName throws Exception1,Exception2,.. { }当方法抛出上面的Exception1,Exception2,.. 异常时,方法将不对这些类型及其子类类型的异常作处理,而由调用该方法的调用者去处理。如果调用者不想处理该异常,可以继续向上抛出。如果所有方法都层层上抛获取的异常,最终JVM会进行处理(打印异常消息和堆栈信息)。
throw关键字总是出现在函数体中,用来抛出一个Throwable类型的异常。语法格式:
// 例如抛出一个IOException类的异常对象: throw new IOException;throw语句后的语句执行不到。如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须检查处理抛出的异常。
下面的列表是 Throwable 类的主要方法:
方法名说明public String getMessage()返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。public Throwable getCause()返回一个Throwable 对象代表异常原因。public void printStackTrace()打印toString()结果和栈层次到System.err,即错误输出流。public String toString()使用getMessage()的结果返回类的串级名字。1. runtimeException子类:
异常说明java.lang.ArrayIndexOutOfBoundsException数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。java.lang.ArithmeticException算术条件异常。譬如:整数除零等。java.lang.NullPointerException空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等java.lang.ClassNotFoundException找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。java.lang.NegativeArraySizeException数组长度为负异常java.lang.ArrayStoreException数组中包含不兼容的值抛出的异常java.lang.SecurityException安全性异常java.lang.IllegalArgumentException非法参数异常2.IOException
异常说明IOException操作输入流和输出流时可能出现的异常。EOFException文件已结束异常FileNotFoundException文件未找到异常3. 其他
异常说明ClassCastException类型转换异常类ArrayStoreException数组中包含不兼容的值抛出的异常SQLException操作数据库异常类NoSuchFieldException字段未找到异常NoSuchMethodException方法未找到抛出的异常NumberFormatException字符串转换为数字抛出的异常StringIndexOutOfBoundsException字符串索引超出范围抛出的异常IllegalAccessException不允许访问某类异常InstantiationException当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常建议:当你需要一个地方来执行在任何情况下都必须执行的代码时,使用finally块。比如当你的程序中使用了外界资源,如数据库连接,文件等,使用finally块来释放资源。 4. 不要一次捕获所有异常
try { method1(); //method1抛出ExceptionA method2(); //method1抛出ExceptionB method3(); //method1抛出ExceptionC } catch(Exception e) { …… }这里有两个潜在的缺陷 - 分别处理就不能实现:针对try块中抛出的每种Exception,很可能需要不同的处理和恢复措施 - 代码中捕获了所有可能抛出的RuntimeException而没有作任何处理,掩盖了编程的错误,会导致程序难以调试。
正确代码:
try { method1(); //method1抛出ExceptionA method2(); //method1抛出ExceptionB method3(); //method1抛出ExceptionC } catch(ExceptionA e) { …… } catch(ExceptionB e) { …… } catch(ExceptionC e) { …… }