trycatchoc try catch finallyy实现方式快捷键

try catch finally的执行顺序深入分析
字体:[ ] 类型:转载 时间:
首先执行try,如果有异常执行catch,无论如何都会执行finally,当有return以后,函数就会把这个数据存储在某个位置,然后告诉主函数,我不执行了,接下来你执行吧,所以函数就会推出
首先执行try,如果有异常执行catch,无论如何都会执行finally 一个函数中肯定会执行finally中的部分。 关于一个函数的执行过程是,当有return以后,函数就会把这个数据存储在某个位置,然后告诉主函数,我不执行了,接下来你执行吧,所以函数就会推出。 但是当一个函数中出现finally以后,finally永远都要执行,所以,就算try或者catch中已经执行了return了,但是这时函数不会退出,不会告诉主函数去执行,而是等待finally执行完了才回去告诉主函数去执行,这时候如果finally中出现了return的话,这次return的值就会覆盖掉try或者catch中的值,然后才会告诉主函数:我不执行了,你去执行吧。所以主函数会得到finally中的返回值。也就是说子函数的返回值永远是finally中的返回值(只要被调用的函数中有值)
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具看了一位博友的一片文章,讲解的是关于java中关于try、catch、finally中一些问题
下面看一个例子(例1),来讲解java里面中try、catch、finally的处理流程
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";
} catch (Exception e) {
// result = "catch";
t = "catch";
} finally {
t = "finally";
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
  首先程序执行try语句块,把变量t赋值为try,由于没有发现异常,接下来执行finally语句块,把变量t赋值为finally,然后return t,则t的值是finally,最后t的值就是finally,程序结果应该显示finally,但是实际结果为try。为什么会这样,我们不妨先看看这段代码编译出来的class对应的字节码,看虚拟机内部是如何执行的。
我们用javap -verbose TryCatchFinally 来显示目标文件(.class文件)字节码信息
系统运行环境:mac os lion系统 64bit
jdk信息:Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-11M3527)&Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode)
编译出来的字节码部分信息,我们只看test方法,其他的先忽略掉
public static final java.lang.String test();
Stack=1, Locals=4, Args_size=0
#16; //String
#18; //String try
#20; //String finally
#22; //String catch
#20; //String finally
#20; //String finally
Exception table:
target type
Class java/lang/Exception
LineNumberTable:
line 15: 8
line 9: 11
line 10: 13
line 12: 14
line 13: 17
line 15: 19
line 13: 22
line 14: 24
line 15: 25
line 16: 28
LocalVariableTable:
Ljava/lang/String;
Ljava/lang/Exception;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 13
locals = [ class java/lang/String ]
stack = [ class java/lang/Exception ]
frame_type = 74 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
首先看LocalVariableTable信息,这里面定义了两个变量 一个是t String类型,一个是e Exception 类型
接下来看Code部分
第[0-2]行,给第0个变量赋值&&,也就是String t="";
第[3-6]行,也就是执行try语句块 赋值语句 ,也就是 t = "try";
第7行,重点是第7行,把第s对应的值"try"付给第三个变量,但是这里面第三个变量并没有定义,这个比较奇怪
第[8-10] 行,对第0个变量进行赋值操作,也就是t="finally"
第[11-12]行,把第三个变量对应的值返回
通过字节码,我们发现,在try语句的return块中,return 返回的引用变量(t 是引用类型)并不是try语句外定义的引用变量t,而是系统重新定义了一个局部引用t&,这个引用指向了引用t对应的值,也就是try ,即使在finally语句中把引用t指向了值finally,因为return的返回引用已经不是t ,所以引用t的对应的值和try语句中的返回值无关了。
下面在看一个例子:(例2)
1 public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";
} catch (Exception e) {
// result = "catch";
t = "catch";
} finally {
t = "finally";
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
这里稍微修改了 第一段代码,只是在finally语句块里面加入了 一个 return t 的表达式。
按照第一段代码的解释,先进行try{}语句,然后在return之前把当前的t的值try保存到一个变量t',然后执行finally语句块,修改了变量t的值,在返回变量t。
这里面有两个return语句,但是程序到底返回的是try 还是 finally。接下来我们还是看字节码信息
public static final java.lang.String test();
Stack=1, Locals=2, Args_size=0
#16; //String
#18; //String try
#20; //String catch
#22; //String finally
Exception table:
target type
Class java/lang/Exception
LineNumberTable:
line 10: 9
line 12: 10
line 13: 13
line 14: 16
line 15: 17
line 16: 20
LocalVariableTable:
Ljava/lang/String;
Ljava/lang/Exception;
StackMapTable: number_of_entries = 3
frame_type = 255 /* full_frame */
offset_delta = 9
locals = [ class java/lang/String ]
stack = [ class java/lang/Exception ]
frame_type = 70 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
frame_type = 0 /* same */
这段代码翻译出来的字节码和第一段代码完全不同,还是继续看code属性
第[0-2]行、[3-5]行第一段代码逻辑类似,就是初始化t,把try中的t进行赋值try
第6行,这里面跳转到第17行,[17-19]就是执行finally里面的赋值语句,把变量t赋值为finally,然后返回t对应的值
我们发现try语句中的return语句给忽略。可能jvm认为一个方法里面有两个return语句并没有太大的意义,所以try中的return语句给忽略了,直接起作用的是finally中的return语句,所以这次返回的是finally。
接下来在看看复杂一点的例子:(例3)
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";
Integer.parseInt(null);
} catch (Exception e) {
t = "catch";
} finally {
t = "finally";
// System.out.println(t);
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
这里面try语句里面会抛出&java.lang.NumberFormatException,所以程序会先执行catch语句中的逻辑,t赋值为catch,在执行return之前,会把返回值保存到一个临时变量里面t ',执行finally的逻辑,t赋值为finally,但是返回值和t',所以变量t的值和返回值已经没有关系了,返回的是catch
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";
Integer.parseInt(null);
} catch (Exception e) {
t = "catch";
} finally {
t = "finally";
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
这个和例2有点类似,由于try语句里面抛出异常,程序转入catch语句块,catch语句在执行return语句之前执行finally,而finally语句有return,则直接执行finally的语句值,返回finally
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";
Integer.parseInt(null);
} catch (Exception e) {
t = "catch";
Integer.parseInt(null);
} finally {
t = "finally";
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
这个例子在catch语句块添加了Integer.parser(null)语句,强制抛出了一个异常。然后finally语句块里面没有return语句。继续分析一下,由于try语句抛出异常,程序进入catch语句块,catch语句块又抛出一个异常,说明catch语句要退出,则执行finally语句块,对t进行赋值。然后catch语句块里面抛出异常。结果是抛出java.lang.NumberFormatException异常
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";
Integer.parseInt(null);
} catch (Exception e) {
t = "catch";
Integer.parseInt(null);
} finally {
t = "finally";
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
这个例子和上面例子中唯一不同的是,这个例子里面finally 语句里面有return语句块。try catch中运行的逻辑和上面例子一样,当catch语句块里面抛出异常之后,进入finally语句快,然后返回t。则程序忽略catch语句块里面抛出的异常信息,直接返回t对应的值 也就是finally。方法不会抛出异常
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";
Integer.parseInt(null);
} catch (NullPointerException e) {
t = "catch";
} finally {
t = "finally";
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
这个例子里面catch语句里面catch的是NPE异常,而不是java.lang.NumberFormatException异常,所以不会进入catch语句块,直接进入finally语句块,finally对s赋值之后,由try语句抛出java.lang.NumberFormatException异常。
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";
Integer.parseInt(null);
} catch (NullPointerException e) {
t = "catch";
} finally {
t = "finally";
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
和上面的例子中try catch的逻辑相同,try语句执行完成执行finally语句,finally赋值s 并且返回s ,最后程序结果返回finally
public class TryCatchFinally {
@SuppressWarnings("finally")
public static final String test() {
String t = "";
t = "try";return
} catch (Exception e) {
t = "catch";
} finally {
t = "finally";
String.valueOf(null);
public static void main(String[] args) {
System.out.print(TryCatchFinally.test());
这个例子中,对finally语句中添加了String.valueOf(null), 强制抛出NPE异常。首先程序执行try语句,在返回执行,执行finally语句块,finally语句抛出NPE异常,整个结果返回NPE异常。
对以上所有的例子进行总结
1 try、catch、finally语句中,在如果try语句有return语句,则返回的之后当前try中变量此时对应的值,此后对变量做任何的修改,都不影响try中return的返回值
2 如果finally块中有return 语句,则返回try或catch中的返回语句忽略。
3 如果finally块中抛出异常,则整个try、catch、finally块中抛出异常
所以使用try、catch、finally语句块中需要注意的是
1 尽量在try或者catch中使用return语句。通过finally块中达到对try或者catch返回值修改是不可行的。
2 finally块中避免使用return语句,因为finally块中如果使用return语句,会显示的消化掉try、catch块中的异常信息,屏蔽了错误的发生
3 finally块中避免再次抛出异常,否则整个包含try语句块的方法回抛出异常,并且会消化掉try、catch块中的异常
阅读(...) 评论()<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&&&&&&&&&上一篇介绍了如何给未检查异常快速增加try/catch语句,这里在补充一点其他相关操作。有时候我们增加了try/catch之后还需要在加一个finally块,比如上每次分配一个cursor最好在末尾增加finally块,在其中关闭cursor防止内存泄露。上cursor总共可占用内存的大小是2M,如果哪个应用的高频方法没有及时关闭cursor的话,会造成其它模块都无法分配cursor的严重后果。下面我们就介绍如何增加finally块的快捷操作。&&&&&&& 步骤一:基于上一篇,增加好try/catch语句,将光标放在try这一行:&&&&&&& &&&&&&& 步骤二:按Ctrl&#43;1,就会提示增加finally块,完工:&&&&&&& &&&&&&&& 最后再补充一些其他东东:将光标放到try语句那一行,按Ctrl&#43;1键能提示增加finally块;将光标放到catch那一行,按Ctrl&#43;1能提示删除try/catch语句。这些操作同样对于增加,while循环块起作用,自己可以尝试下。&&&&&&& 上一篇文章,Eclipse用法和八:自动添加try/catch块1:&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &http://blog.csdn.net/ts1122/article/details/8886219&&&&&& 下一篇文章,Eclipse用法和技巧十:显示代码outline:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& http://blog.csdn.net/ts1122/article/details/8933207<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&

我要回帖

更多关于 oc try catch finally 的文章

 

随机推荐