java异常一点点

引言

1 OutputStreamWriter out = ...
2 java.sql.Connection conn = ...
3 try {
4  Statement stat = conn.createStatement();
5  ResultSet rs = stat.executeQuery(
6   "select uid, name from user");
7  while (rs.next())
8  {
9   out.println("ID:" + rs.getString("uid")
10    ",姓名:" + rs.getString("name"));
11  }
12  conn.close();
13  out.close();
14 }
15 catch(Exception ex)
16 {
17  ex.printStackTrace();
18 }

15行-18行:吃掉异常

15行:没有指定异常

3行-14行:不能保证占用的资源(数据库连接,流)被释放

17行:如果多个地方都直接用这种方式来打印异常,不易读,增加查找问题成本

3行-14行:try的地方太大,不易判断具体是哪行语句抛出的异常

7行-11行:如果在循环中抛出异常,会让使用这些数据的人或设备将收到一份不完整的(因而也是错误的)数据,却得不到任何有关这份数据是否完整的提示

基本知识

Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。

Throwable----Error
         ----Exception----RuntimeException
                      ----其他异常
The Throwable class is the superclass of all errors and
exceptions in the Java language. Only objects that are instances of this
class (or one of its subclasses) are thrown by the Java Virtual Machine or
can be thrown by the Java throw statement. Similarly, only
this class or one of its subclasses can be the argument type in a
catch clause.

Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选 择线程终止。

  • A method is not required to declare in its throws
    clause any subclasses of Error that might be thrown
    during the execution of the method but not caught, since these
    errors are abnormal conditions that should never occur.


Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。程序中应当尽可能去处理这些异常。

  • The class Exception and its subclasses are a form of
    Throwable that indicates conditions that a reasonable
    application might want to catch.

运行时异常都是RuntimeException类及其子类异常,如NullPointerException、 IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引 起的,程序应该从逻辑角度尽可能避免这类异常的发生。

非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

实例

public static void main(String[] args) {
        TestException te = new TestException();
        System.out.println(te.testException1());
        System.out.println("hello world!");
    }

    public int testException1(){
        int i = 0;
        i = 1/i;
        return i;
    }

执行结果:抛出运行时异常,jvm默认处理打印异常信息,停止执行程序

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at TestException.testException1(TestException.java:13)
	at TestException.main(TestException.java:8)
public static void main(String[] args) {
        TestException te = new TestException();
        try {
            System.out.println(te.testException2());
        } catch (Exception e) {
            System.out.println("In the main exception!");
        }
        System.out.println("hello world!");
    }

    public int testException2() throws Exception{
        int i = 0;
        i = 1/i;
        return i;
    }

执行结果:捕捉到运行时异常,并按照程序进行处理,在调用方法时必须对异常进行处理

In the main exception!
hello world!
public static void main(String[] args) {
        TestException te = new TestException();

        try {
            System.out.println(te.testException4());
        } catch (Exception e) {//捕获
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("hello world!");//正常
    }

    public int testException4() throws Exception{
        int i = 0;
        try{
            i = 1/i;
        }catch(Exception e){
            throw e;//抛出
        }
        return i;
    }

执行结果:抛出/捕捉/正常,方法中有throw的时候需要搭配throws(不是必须的,后面有例子)

public static void main(String[] args) {
        TestException te = new TestException();

        System.out.println("first time:"+te.testException5(1));
        System.out.println("first time:"+te.testException5(0));
    }

    public String testException5(int value){
        int result;
        try{
            result=1/value;
            return "try return!";
        }catch(Exception e){
            return "catch return";
        }finally{//会有警告:finally block does not complete normally
            return "finally return!";//每次返回的都是这个值   }

       //return "end of method!" 以为在finally中存在return,这里为不可达代码,编译报错,不可答代码
    }

结果:在try catch finally中都return,则不论抛不抛出异常,最后返回的值是finally中的

first time:finally return!
first time:finally return!
public String testException5(int value){
        int result;
        try{
            result=1/value;
            return "try return!";
        }catch(Exception e){
            e.printStackTrace();
            throw e;
        }finally{
            return "finally return!";
        }
    }

执行结果:在catch中捕捉到异常,但是抛不出来,仍然正常执行finally中的return

first time:finally return!
java.lang.ArithmeticException: / by zero
	at TestException.testException5(TestException.java:16)
	at TestException.main(TestException.java:10)
first time:finally return!
public static void main(String[] args) {
        TestException te = new TestException();

        System.out.println("first time:"+te.testException5(1));
        System.out.println("first time:"+te.testException5(0));
    }

    public int testException5(int value){
        int result = 1;
        int result1 = 1;
        try{
            result=1/value;
            result1++;
            return result1;
        }catch(Exception e){
            result1 += 5;
            return result1;
        }finally{
            result1 += 10;
            System.out.println("in the finally:"+result1);
        }

        //return result1;编译出错,不可达代码

    }

执行结果:执行到finally中的result1+10操作,但是并不能影响在try和catch中的return的result的值

in the finally:12
first time:2
in the finally:16
first time:6
public int testException5(int value) {
        int result1 = 1;
        try {
            return result1;
        } catch (Exception e) {
            return result1;
        } finally {
            result1=2;
        }

    }

      public int testException5(int value);
     0  iconst_1
     1  istore_2 [result1]
     2  iload_2 [result1]
     3  istore 5
//-----------------------注意,内联finally中的代码----------------------------//
     5  iconst_2
     6  istore_2 [result1]
//-----------------------end-----------------------------------------------//
     7  iload 5
     9  ireturn
    10  astore_3 [e]
    11  iload_2 [result1]
    12  istore 5
//-----------------------注意,内联finally中的代码----------------------------//
    14  iconst_2
    15  istore_2 [result1]
//-----------------------end-----------------------------------------------//
    16  iload 5
    18  ireturn
//-----------------------其他情况执行到这里,比如在catch中又出现exception-------//
    19  astore 4 //保存之前的返回地址
    21  iconst_2
    22  istore_2 [result1]
    23  aload 4  //如果有return直接返回
    25  athrow   //没有return抛出栈顶异常
//--------------------------------------end--------------------------------//
      Exception Table:
        [pc: 2, pc: 5] -> 10 when : java.lang.Exception //在pc2-4之间出现exception时跳到10
        [pc: 2, pc: 5] -> 19 when : any //在2-4之间不论出现什么情况都到19
        [pc: 10, pc: 14] -> 19 when : any //在10-13之间不论什么情况都到19
public int testException5(int value) {
        int result1 = 1;
        try {
            result1 = 3;
            return result1;
        } catch (Exception e) {
            result1 = 4;
            return result1;
        } finally {
            result1=2;
            return result1;
        }

    }
     0  iconst_1
     1  istore_2 [result1]
     2  iconst_3
     3  istore_2 [result1]
     4  goto 14              //finally中有return,try中的return直接优化掉,直接goto
     7  astore_3 [e]
     8  iconst_4
     9  istore_2 [result1]
    10  goto 14              //finally中有return,catch中的return直接优化掉,直接goto
    13  pop
    14  iconst_2
    15  istore_2 [result1]
    16  iload_2 [result1]
    17  ireturn
public static void main(String[] args) {
        TestException te = new TestException();
        te.testException5(1);
    }

    public int testException5(int value) {
        int result1 = 1;
        try {
            result1 = 3;
        } catch (Exception e) {
            result1 = 4;
        } finally {
            result1=2;
        }
        return result1;
    }
     0  iconst_1
     1  istore_2 [result1]
     2  iconst_3
     3  istore_2 [result1]
     4  goto 22                      //都没有return,直接goto到finally部分
     7  astore_3 [e]
     8  iconst_4
     9  istore_2 [result1]
    10  iconst_2
    11  istore_2 [result1]
    12  goto 24
    15  astore 4
    17  iconst_2
    18  istore_2 [result1]
    19  aload 4                           //
    21  athrow                            //finally中无return,正常字节码
    22  iconst_2
    23  istore_2 [result1]
    24  iload_2 [result1]
    25  ireturn

理论

1. 编译后的异常表是有顺序的,当出现异常的时候会去按找顺序匹配,匹配到程序转到相应的地方执行。首先按照pc行数,然后判断类型是否符合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值