java 异常处理机制(java 编程思想)

一、概念 

  • “异常”这个词有“我对此感到意外”的意思。问题出现了,你也许并不清楚该如何处理,但你的确知道不应该置之不理;你要停下来,看看是不是有别人或在别的地方,能够处理这个问题。只是在当前的环境中还没有足够的信息来解决这个问题,所以就把这个问题提交到一个更高级别的环境中,在这里将作出正确的决定。

二、基本知识

2.1 基本异常

  • 当抛出异常后,首先,同Java中其它的对象创建一样,将使用 new在堆上创建异常对象。然后,当前的执行路径(它不能继续下去了)被终止,并且从当前环境中弹出对异常对象的引用。此时,异常处理机制接管程序,并开始寻找一个恰当的地方来继续执行程序。这个恰当的地方就是异常处理程序,它的任务是将程序从错误状态中恢复,以使程序能要么换一种方式运行,要么继续运行下去。异常允许我们(如果没有其它手段)强制程序停止运行,并告诉我们出现了什么问题,或者(理想状态下)强制程序处理问题,并返回到稳定状态。

  在基本异常的基础之上,我们还需要知道异常的参数:

  • 我们总是用 new 在堆上创建异常对象,这也伴随着存储空间的分配和构造器的调用。所有标准异常类都有两个构造器:一个是默认构造器;另一个是接受字符串作为参数,以便能把相关信息放入异常对象的构造器: 

      throw new NullpointerException("t = null "); 

  • 在使用 new 创建异常对象之后,此对象的引用将传给 throw。将会返回一个异常对象然后退出方法或作用域。
  • 能够抛出任意类型的Throwable对象,它是异常类型的根类。通常,对于不同类型的错误,要抛出相应的异常。错误信息可以保存在异常对象内部或者使用异常类的名称来暗示。上一层环境通过这些信息来决定如何处理异常。(通常,异常对象中仅有的信息就是异常类型,除此之外不包含任何有意义的内容。)

2.2 捕获异常

  try 块捕获异常

  如果在方法内部抛出了异常(或者在方法内部调用的其他方法抛出了异常),这个方法将在抛出异常的过程中结束。要是不希望方法就此结束,可以在方法内设置一个特殊的块来捕获异常。

  catch块处理异常

  当然,抛出的异常必须在某处得到处理。这个“地点”就是异常处理程序,而且针对每个要捕获的异常,得准备相应的处理程序。异常处理程序紧跟在 try 块之后,以关键字 catch 表示:

try{
    //Code that might generate exceptions
}catch(Type1 id1){
    //handle exceptions of Type1
}catch(Type2 id2){
    //handle exceptions of Type2
}
//etc...

  异常处理程序必须紧跟在 try 块之后。当异常被抛出时,异常处理机制将负责搜寻参数与异常类型相匹配的第一个处理程序。然后进入 catch 子句执行,此时认为异常得到了处理。一旦 catch 子句结束,则处理程序的查找过程结束。注意,只有匹配的 catch 子句才能得到执行。

  两种异常处理模型: 终止模型、恢复模型

  终止模型: 一旦异常被抛出,就表明错误已经无法挽回,也不能回来继续执行。

  恢复模型: 异常处理程序的工作是修正错误,然后重新尝试调出问题的方法,并认为第二次能成功。 该种模型时,不能再遇见错误时就抛出异常,而是调用方法来修正,或者把try块放在while循环里,这样不断的进入try块直到得到满意的结果。

2.3 创建自定义异常

  通过自定义MyException继承自Exception来创建自定义的异常。

class MyException extends Exception{
    public MyException(){}
    public MyException(String in){
        super(in);
    }
}

  并在catch中通过:

      e.printStackTrace()

将异常写入到System.err(标准错误流),在debug的时候会显示错误的函数和行号(这是对System.out的优势)。

(它将打印“从方法调用处直到异常抛出处”的方法调用序列)

栈轨迹:

  printStackTrace方法也可以通过getStackTrace()方法来访问,这个方法将返回一个由栈轨迹中的元素构成的数组,其中每一个元素都将表示栈中的一帧。

元素0是栈顶元素,并且是调用序列中的最后一个方法调用。

  通过如下代码打印 栈轨迹:

     try {
            f();
        } catch (MyException e) {
      //      e.printStackTrace();
            for(StackTraceElement ste : e.getStackTrace()){
                Log.d(TAG, "onClick: "+ste.getMethodName());
            }
        }

得到的结果如下:

  

2.4 异常说明

  如果调用某个方法,方法里的代码产生了异常却没有进行处理,编译器会发现这个问题: 要么处理这个异常,要么在函数异常说明中表明此方法将产生异常。

如下图所示: 1、函数声明加: throws MyException    2、函数中 增加 try catch 处理异常。 

2.5 try catch中有return,final?

  当try/catch代码中有return语句,那么此时的final是否还会继续执行?

       1、 当try catch中有return 语句,在执行return之前将需要return的结果保存在一个临时变量中,然后去执行finally代码块,执行完之后再执行return。

       2、 1中情况有个前提条件是finally中没有return语句,如果finally代码块中也有return,那么会执行finally中的return,不会执行try/catch中的。

int testFinallyReturn(){
        int x = 1;
        try{
            x++;
            return x;
        }catch (Exception e){
            return x;
        }finally {
            ++x;
            return x;
        }
    }

运行结果:
if(exist("return x") in finally){
return result : 2 ;
}else{
  return result : 3 ;
}
原文地址:https://www.cnblogs.com/NeilZhang/p/7639546.html