异常是指程序运行时(非编译时)所发生的非正常情况或错误,当程序违反了语义规则时,JVM就会将出现的错误表示为一个异常并抛出。这个异常可以在catch程序中进行捕获,然后进行处理。而异常处理的目的则是为了提高程序的安全性和鲁棒性。
JAVA提供了两种错误的异常类,分别为Error和Exception
Error:表示在程序运行期间出现了非常严重的错误,并且该错误是不可恢复的,由于这属于JVM层次的严重错误,因此这种错误是会导致程序终止执行的。此外编译器不会检查Error是否被处理,因此在程序中不推荐捕获Error类型的异常。 OutOfMemoryError、ThreadDeath等都属于错误。
throwable
Exception:表示可以恢复的异常,是编译器可以捕捉到的。
- 运行时异常(runtime exception):编译器没有强制对运行时异常进行捕获并处理,如果不对这种异常进行处理,当出现这种异常时,会由JVM来处理,出现运行时异常后,系统会一直网上曾抛,直到遇到处理代码位置。若没有处理块,如果是线程,那么这个线程就退出了,如果是主程序异常那么整个程序就退出了。所以,如果不对运行时异常进行处理,后果是非常严重的,一旦发生,要么线程终止,要么是主程序终止。
- 检查异常(checked exception):所有继承自Exception不是运行时异常的异常都是检查异常,比如常见的IO和SQL异常。这种异常都发生在编译阶段,Java编译器强制程序去捕获此类异常。这种异常一般在如下几种情况中使用:【1】异常的发生不会导致程序出错,进行处理后可以继续执行后续的操作,例如,当连接数据库失败后,可以重新连接后进行后续操作。【2】程序依赖于不可靠的外部条件,例如系统IO。
注意:
Java的异常处理中,finally块的作用就是为了保证无论出现什么情况,finally块里的代码一定会被执行,由于程序执行return就意味着结束对当前函数的调用并跳出这个函数体,因此任何语句要执行都只能在return前执行(除非碰到exit函数),因此finally块里的代码也是在return前执行的。此外如果try-finally或者catch-finally中都有return,那么finally块中的return语句将会覆盖别处的return语句,最终返回到调用者那里的是finally中return的值。此外由于在一个方法内部定义的变量都存储在栈中,当这个函数结束后,其对应的栈就会被回收,此时在其方法体中的变量就不存在了,因此return在返回时不是直接返回变量的值,而是复制一份,然后返回。因此,对于基本类型的数据,在finally中改变return的值对返回结果没有影响,而对引用了理性的数据会有影响。
public class Test1 { public static int testFinally1(){ int result = 1; try{ result = 2; return result; }catch(Exception e){ return 0; }finally{ result = 3; System.out.println("execute finally1"); } } public static StringBuffer testFinally2(){ StringBuffer s = new StringBuffer("hello"); try{ return s; }catch(Exception e){ return null; }finally{ s.append("world"); System.out.println("execute finally2"); } } public static void main(String[] args) { System.out.println(Test1.testFinally1()); System.out.println(Test1.testFinally2()); } }