1.异常的分类
1) Checked exception: 这类异常都是Exception的子类 。异常的向上抛出机制进行处理,如果子类可能产生A异常,那么在父类中也必须throws A异常。可能导致的问题:代码效率低,耦合度过高。C#中就没有使用这种异常机制。
2) Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是特殊的,它们不能通过client code来试图解决,所以称为Unchecked exception 。RuntimeException(运行时异常),不需要try...catch...或throws 机制去处理的异常。
1.2Java异常
Java 提供了两类主要的异常:runtimeException 和 checkedException;一般异常(checkedException)主要是指 IO 异常等。对于这种异常,JVM 要求我们必须对其进行 cathc 处理,所以,面对这种异常,要写一大堆的 catch 块去处理可能出现的异常。运行时异常(runtimeException)(Unchecked exception)我们一般不处理,当出现这类异常的时候程序会由虚拟机接管。比如,我们从来没有去处理过 NullPointerException。
1.3Java异常处理
出现运行时异常的时候,程序会将异常一直向上抛,一直抛到遇到处理代码,如果没有 catch 块进行处理,到了最上层,如果是多线程就有 Thread.run()抛出,如果不是多线程 那么就由main.run()
抛出。抛出之后,如果是线程,那么该线程也就终止了,如果是主程序,那么该程序也就终止了。其实运行时异常的也是继承自 Exception,也可以用 catch 块对其处理,只是我们一般不处理罢了,也就是说,如果不对运行时异常进行 catch 处理,那么结果不是线程退出就是 主程序终止。如果不想终止,那么我们就必须捕获所有可能出现的运行时异常。如果程序中出现了异常数据,但是它不影响下面的程序执行,那么我们就该在catch块里面将异常数据舍弃, 然后记录日志。如果,它影响到了下面的程序运行,那么还是程序退出比较好些。
2.Java异常的继承结构(网上借鉴)
3.Java检查性异常捕获
3.1java异常处理机制
在Java应用程序中,异常处理机制为:抛出异常,捕捉异常。
抛出异常
:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。捕获异常
:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。
任何 Java 代码都可以抛出异常,如:自己编写的代码、来自 Java 开发环境包中代码,或者 Java 运行时系统。无论是谁,都可以通过 Java 的 throw 语句抛出异常。从方法中抛出的任何异常都必须使用 throws
子句,捕捉异常通过 try-catch
语句或者 try-catch-finally
语句实现。
3.2关键字说明
Java通过面向对象的方式对异常进行处理,Java 把异常按照不同的类型进行分类,并提供了良好的接口。在 Java 中,每个异常都是一个对象,它都是 Throwable 或其子类的实例。当一个方法出现异常后就会抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并对异常进行处理。Java 的异常处理是通过5个 关键词来实现的:try、catch、throw、throws、finally。
try
:用来指定一块预防所有异常的程序catch
:紧跟在try后面,用来捕获异常throw
:用来明确的抛出一个异常throws
:用来标明一个成员函数可能抛出的各种异常finally
:确保一段代码无论发生什么异常都会被执行的一段代码。
4.Java异常的其他说明
当使用多个 catch 语句块来捕获异常时,需要将父类的 catch 语句块放到子类型的 catch 块之后,这样才能保证后续的 catch 可能被执行,否则子类型的 catch 将永远无法到达,Java 编译器会报编译错误。如果 try 语句块中存在 return 语句,那么首先会执行 finally 语句块中的代码,然后才返回。如果 try 语句块中存在 System.exit(0)
语句,那么久不会执行 finally 语句块的代码了,因为 System.exit(0)
会终止当前运行的 JVM,程序在 JVM 终止前结束执行。
4.1测试代码
@Test public void testException2() { try { throw new Exception(); } catch (java.io.FileNotFoundException ex) { System.out.print("FileNotFoundException!"); } catch (java.io.IOException ex) { System.out.print("IOException!"); } catch (java.lang.Exception ex) { System.out.print("Exception!"); } } @Test public void testException1(){ /* try { int s = 12/0; System.out.print("TRY里面"); }catch (Exception e){ e.printStackTrace(); } */ int s = 12/0; System.out.print("TRY外面"); }