文档章节

try,catch,finally的一点小疑惑

WilliamQ
 WilliamQ
发布于 2015/10/21 23:36
字数 737
阅读 15
收藏 0

老规矩,先来看下这样两段代码的输出结果:

代码A:

public class TestA {

	public static void main(String[]args){		
		System.out.println(inc());
	}
	
	public static T inc(){
		T t = new T();
		try{
			t.a = 1;
			if(t.a == 1){
				throw new NullPointerException();
			}
			return t;
		}catch(Exception e){
			t.a = 2;
			return t;
		}finally{
			t.a = 3;
		}
	}
}

public class T{
	public int a = 4;
	public String toString(){
		return "T [a="+a+"]";
	}
}

代码B:

public class StaticTest {

	public static void main(String[]args){		
		System.out.println(inc());
	}
	
	public static Integer inc(){
		Integer a = 0;
		try{
			a = 1;
			if(a == 1){
				throw new NullPointerException();
			}
			return a;
		}catch(Exception e){
			a = 2;
			return a;
		}finally{
			a = 3;
		}
	}
}

以上的两段代码是完整的笔试代码:

代码A的结果是:T[a=3]

代码B的结果是:2

我在第一眼看到这个题目是,立即得出结果,

T[a=3]

3

为什么我会得出这样的结果呢?

因为我把return和finally的执行顺序搞乱了,以前一直以为,return的执行应该是最后一步,所以finally在return前先执行。这种想法当然是错误的,其实:

在整个try,catch,finally块中,finally自然应该是最后执行的,当try或者catch中已经有了return后,先执行return操作,然后执行finally,finally执行完成后再将之前的值return回去,随后执行的finally是不会影响到return的值的。

当我一个朋友看明白这里的说法后,马上就说:原来如此,那结果不就应该是:

T[a=2]

2

这当然是不正确的,正如我所说的finally的执行不会影响到return的值,所以代码A的返回自然是t对象没错。然而java中采用的是引用传递而非值传递,所以这里返回的只是t对象的引用,finally里面的代码虽然没有改变返回的引用值,确实改变了引用指向的对象的值。


讲到这里其实这个问题已经解决了,下面是我曾经关于try,catch,finally的几个小误解:

1.try和finally是必须一起使用的,但是catch块就可以去掉;

2.finally里面的内容并非一定会执行,当try块之前程序已经return,则不会执行try里面的内容,也不会执行到对应的finally里面的内容。当try块或catch块中存在:System.exit(0) 这时JVM被结束掉,程序自然没法继续往下执行;

3.finally语句是在try的return语句执行之后,return返回之前执行(这句是在前辈的总结中看到的,我觉得比我总结的好);

4.不要再finally里面使用return,因为这是没有意义的(至少我这样认为,你的代码将不会再有其他的输出。。。)。

© 著作权归作者所有

共有 人打赏支持
WilliamQ
粉丝 0
博文 6
码字总数 2381
作品 0
深圳
私信 提问
Java finally语句与return语句执行顺序解析

网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过我试验,至少有两种情况下finally语句是不会...

passionfly
2015/04/18
0
0
异常处理遇到过的那些坑

今年有个目标之一就是提升团队代码的质量,所以时常会思索如何把这件事做到更好,不想教条主义,也不想搞出一个代码规范,强制团队照着做,落地的效果不好,反而把大家的积极性给弄没了。所以...

谢东升Forest
2017/07/27
0
0
(转)java 中的try catch finally 语句中含有return语句的执行情况(总结版)

原处:http://blog.csdn.net/ns_code/article/details/17485221 在这里看到了try catch finally块中含有return语句时程序执行的几种情况,但其实总结的并不全,而且分析的比较含糊。但有一点...

huwenchi111
2017/01/13
0
0
关于 Java 中 finally 语句块的深度辨析

文章来自 IBM developerWorks 可不能小看这个简单的 finally,看似简单的问题背后,却隐藏了无数的玄机。接下来我就带您一步一步的揭开这个 finally 的神秘面纱。 问题分析 首先来问大家一个...

IBMdW
2011/07/15
285
4
关于IO流的一点小问题

public class Demo6{ public static void main(String[] args) { write(); } private static void write() { OutputStream out=null; DataOutputStream dout=null; File file= new File("src......

kong_resty
2012/03/15
160
5

没有更多内容

加载失败,请刷新页面

加载更多

Intellij IDEA中设置了jsp页面,但是在访问页面时却提示404

在Intellij IDEA中设置了spring boot的jsp页面,但是在访问时,却出现404,Not Found,经过查找资料后解决,步骤如下: 在Run/Debug Configurations面板中设置该程序的Working Directory选项...

uknow8692
昨天
1
0
day24:文档第五行增内容|每月1号压缩/etc/目录|过滤文本重复次数多的10个单词|人员分组|

1、在文本文档1.txt里第五行下面增加如下内容;两个方法; # This is a test file.# Test insert line into this file. 分析:给文档后增加内容,可以用sed 来搞定;也可以用while do done...

芬野de博客
昨天
1
0
深入理解JVM—JVM内存模型

深入理解JVM—JVM内存模型 我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来越快,磁盘远远跟不上CPU的读写速度,才设计了内存...

onedotdot
昨天
1
0
MVC、MVCS、MVVM、MVP、VIPER等这么多架构模式哪一个好呢?

在项目开启阶段,其中一个很重要的环节就是选架构。 那么面对目前已知的这么多架构模式我们该怎么选择呢?这确实是个很让人头疼的问题! 下面我就在这里梳理一下目前常见的一些架构模式。 先...

Java干货分享
昨天
8
0
简单模仿配置文件的反射机制

//Student类 public class Student { public void love() { System.out.println("python"); } } //Tesy类 public class Tesy { public static void main(String[] args) throws Exceptio......

南桥北木
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部