搜到了这篇文章 ,下面说下我自己的问题与理解。
我看完程序给出的输出是:
i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, at the end of try
testEx, finally; return value=false
但(= =)答案是:
i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, finally; return value=false
testEx, finally; return value=false
回头重读程序,发现问题在于方法testEx1那里。
对该程序的分析如下:首先主函数调用方法testEx(),其内部的ret不断指向下一个异常方法,运行到testEx2()时,try内的内容出现异常(除数i=0,此时已输出i=2和i=1),接着进入catch 输出"testEx2, catch exception",ret被置为false。接着是一个throw语句(这个一会儿再说)。进入finally后输出"testEx2, finally; return value=false"(不论异常是否发生finally都会被执行)。此时方法testEx2()结束,为testEx1()中的ret返回false,程序回到testEx1()。
接着问题就来了。if条件成立后,运行里面的return放弃try里后面的语句,但运行return之后testEx1()并不是直接返回到testEx()里的ret,而是接着运行它的finally!随即输出一行testEx1, finally; return value=false,返回一个false。
此时这里又出现一个问题:testEx1()返回给ret的值到底是if里的还是finally里的呢?
所以我将testEx1()中finally内最前面加了一句“ret=true;”。运行程序,输出结果如下:
可见,testEx1()给testEx()返回的是finally内的return而不是try内的。那么try内的return是被后面的覆盖掉了还是根本没有执行呢?我将finally内的return注释掉,发现得到的结果与上面的完全相同!(方法一开始ret有被初始化为true)然后我在 testEx1()内加了一行输出,实验证明if内的代码确实有被执行。往下继续看文章发现“那么写在try或者catch中的return语句也就不会真正的从该函数中跳出了,它的作用在这种情况下就变成了将控制权(语句流程)转到finally块中”。这也就是说try内的return是根本不会把值真正返回去的,而是看到return就直接跳转到finally。这样问题就得到了很好解释。
纵观java的异常处理机制大概是这个意思:try里面包含的是有可能会出现异常的代码,异常真的发生以后转到相应异常类型的catch中 对异常进行处理。catch中对异常的处理又有方法上的区别。第一种比较负责任的方法是,在catch中直接处理异常(输出异常信息 返回一个值);第二种就要用到throw,比如:
boolean testEx() throws Exception{
try {
int i=0;
int a=12/i;
}
catch(Exception e){
System.out.println("可有可无的异常信息提示");
throw e;
rerurn false;
}
finally{
//code
}
}
这里的throw是向上抛出一个异常,意思就是把这个异常实例返回给该方法的调用者,让调用者处理。此时最好在方法名后面加上提示性的“throws Exception”,意在提示该方法的调用者:这个方法里可能会抛出一个Exception类型的异常,你要记得在上层处理它。
当throw被执行时,它所在的try/catch内的后面的代码并不被继续执行,但finally作为异常处理机制的出口 还是依然故我。总结一下就是不论出现什么情况finally都会被运行,finally威武!
这里只是浅显的总结一下java异常处理机制,其它的请看那篇很全面的神文章。
本文有点条理不清,敬请原谅,毕竟我初学java,第一次写技术博客。如有错误欢迎指出~