异常(exception)是正常程序流程不能处理或没有处理的异常情况。比如:数组下标越界,文件不存在等
主要分成两类 1)受检异常:在编译时被编译器检测到 2)非受检异常:不能被编译器检测到。 非受检异常又分为运行时异常(比如除数为0)和错误异常(Error,程序中无法被处理)
主要谈程序能够处理的异常
在java中,异常是以类形式进行封装的(java.lang.Exception及其子类RuntimeException等)。
举例:
public class ExpectionDemo { public static void main(String[] args){ int a=10; int b=0; int c=a/b; System.out.PRintln(a); System.out.println(b); System.out.println(c); }}输出结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero at expection.ExpectionDemo.main(ExpectionDemo.java:7)产生了一个java.lang.ArithmeticException类型的异常
异常能够在执行程序时自动发现并且产生,可以在程序中显式生成,这种显式生成异常的方法叫做抛出异常。通过throw语句实现。
throw
ArithmeticException e = new ArithmeticException(); throw e; 或 throw new ArithmeticException();
try-catch-finally结构
try{ 可能会产生异常的语句XXXXXXXX}catch(Exception1 e1){ XXXXXXXX}catch(Exception2 e2){ XXXXXXXX}... finally{ XXXXXXXX}例如
public class ExceptionDemo { public static void main(String[] args) { try { System.out.println("try语句"); throw new Exception(); } catch (Exception e1) { System.out.println("catch语句"); e1.printStackTrace(); } finally { System.out.println("finally语句"); }//try..结束 }//main结束}执行结果:
try语句catch语句java.lang.Exception at expection.ExpectionDemo.main(ExpectionDemo.java:7)finally语句如果去掉try中的throw语句 执行结果:
try语句finally语句由此可见:
这种结构中,try语句块有异常发生时中断try剩余语句,产生异常实例对象。如果try语句块没有异常产生,那么catch语句不会被执行,而finally一般总是会执行。
throws
throw 用于方法块里面的代码,比如try…catch ….语句块,表示它抛出异常,但它不会处理它,而是由方法块的throws Exception来调用异常处理类来处理。
public class ExpectionDemo { public void exception() throws NumberFormatException{ int a = Integer.parseInt("10L"); } public static void main(String[] args){ ExpectionDemo test = new ExpectionDemo(); try{ test.exception(); }catch(NumberFormatException e){ System.out.println(e.getMessage()); } }}输出结果
For input string: "10L"1)throws 用于抛出方法层次的异常,并且直接由些方法调用异常处理类来处理该异常,所以它常用在方法的后面。比如 public static void main(String[] args) throws SQLException
2)throw 用于方法块里面的代码,比throws的层次要低,比如try…catch ….语句块,表示它抛出异常,但它不会处理它,而是由方法块的throws Exception来调用异常处理类来处理。
1)将异常包含在循环语句块中
如下代码所示,异常包含在 for 循环语句块中。 清单 6
for(int i=0; i<100; i++){ try{ }catch(Exception e){ XXXXXX }}异常处理占用系统资源。一般不会直接犯这样的错误,换个角度,类 A 中执行了一段循环,循环中调用了 B 类的方法,B 类中被调用的方法却又包含 try-catch 这样的语句块。褪去类的层次结构,代码和上面如出一辙。
2)利用 Exception 捕捉所有潜在的异常
一段方法执行过程中抛出了几个不同类型的异常,为了代码简洁,利用基类 Exception 捕捉所有潜在的异常,如下例所示:
public void retrieveObjectById(Long id){ try{ //…抛出 IOException 的代码调用 //…抛出 SQLException 的代码调用 }catch(Exception e){ //这里利用基类 Exception 捕捉的所有潜在的异常,如果多个层次这样捕捉,会丢失原始异常的有效信息 throw new RuntimeException(“Exception inretieveObjectById”, e); }}3)忽略异常
如下异常处理只是将异常输出到控制台,没有任何意义。而且这里出现了异常并没有中断程序,进而调用代码继续执行,导致更多的异常。
public void retrieveObjectById(Long id){ try{ //..some code that throws SQLException }catch(SQLException ex){ /** * 这里的异常打印毫无意义,仅仅是将错误堆栈输出到控制台。 * 而在 Production 环境中,需要将错误堆栈输出到日志。 * 而且这里 catch 处理之后程序继续执行,会导致进一步的问题*/ ex.printStacktrace(); }}这是三个我觉得新手最容易进入的误区 引自Java 异常处理的误区和经验总结
新闻热点
疑难解答