JAVA的异常处理

异常(exception)是正常程序流程不能处理或没有处理的异常情况。比如:数组下标越界,文件不存在等


1.异常种类


主要分成两类
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类型的异常


2.异常的产生


异常能够在执行程序时自动发现并且产生,可以在程序中显式生成,这种显式生成异常的方法叫做抛出异常。通过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"

3.throw和throws


1)throws 用于抛出方法层次的异常,并且直接由些方法调用异常处理类来处理该异常,所以它常用在方法的后面。比如
public static void main(String[] args) throws SQLException

2)throw 用于方法块里面的代码,比throws的层次要低,比如try…catch ….语句块,表示它抛出异常,但它不会处理它,而是由方法块的throws Exception来调用异常处理类来处理。


4.异常处理误区


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 异常处理的误区和经验总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值