`
85977328
  • 浏览: 1903561 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于return和finally

 
阅读更多
本来return和finally也不是个事。之前看虚拟机运行原理的时候就了解过。但是最近被人问起的时候,缺没有说清楚。所以整理一下记录下来。
1.如果返回的是个对象,finally里的的代码,可以改变对象内部的状态。
package com.chinaso.phl;

import java.util.ArrayList;
import java.util.List;

public class Test {

	public static void main(String[] args) throws Exception {
		Test t = new Test();
		System.out.println(t.check());
	}

	public List<String> check() throws Exception {
		List<String> name = new ArrayList<String>();
		name.add("phl");
		try {
			System.out.println("try");
			return name;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("finally");
			name.add("piaohailin");
			for (int i = 0; i < 3; i++) {
				System.out.println("time:" + (i + 1) * 300);
				Thread.sleep(300);
			}
		}
		System.out.println("return");
		name.add("return");
		return name;
	}
}

输出
try
finally
time:300
time:600
time:900
[phl, piaohailin]

2.finally里面的赋值,不会影响返回结果
package com.chinaso.phl;

import java.util.ArrayList;
import java.util.List;

public class Test {

	public static void main(String[] args) throws Exception {
		Test t = new Test();
		System.out.println(t.check());
	}

	public String check() throws Exception {
		String name = "phl";
		try {
			System.out.println("try");
			return name;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("finally");
			name = "piaohailin";
			for (int i = 0; i < 3; i++) {
				System.out.println("time:" + (i + 1) * 300);
				Thread.sleep(300);
			}
		}
		System.out.println("return");
		name = "return";
		return name;
	}
}

输出
try
finally
time:300
time:600
time:900
phl

3.finally里带有return方法,则此return会覆盖try里面的return
//warnning finally block does not complete normally
一般不这么用,因为有警告信息,不够优雅
package com.chinaso.phl;

import java.util.ArrayList;
import java.util.List;

public class Test {

	public static void main(String[] args) throws Exception {
		Test t = new Test();
		System.out.println(t.check2());
	}

	public String check2() throws Exception {
		String name = "phl";
		try {
			System.out.println("try");
			return name;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			System.out.println("finally");
			name = "piaohailin";
			for (int i = 0; i < 3; i++) {
				System.out.println("time:" + (i + 1) * 300);
				Thread.sleep(300);
			}
			return name;
		}
	}
}

输出
try
finally
time:300
time:600
time:900
piaohailin
8
10
分享到:
评论
19 楼 85977328 2014-03-14  
kangzj 写道
个人是这样理解的,Java在处理基本类型和对象上本来就是有差别的,return的时候,可以想象有一块内存区域来存入return的结果,基本类型的话,会直接写入这片内存,而对象,则是写入的引用,至于String,是值对象,每次复制其实都是new了新对象,故改变其值并不会改变return的结果。

回头我用对象试试
18 楼 kangzj 2014-03-14  
个人是这样理解的,Java在处理基本类型和对象上本来就是有差别的,return的时候,可以想象有一块内存区域来存入return的结果,基本类型的话,会直接写入这片内存,而对象,则是写入的引用,至于String,是值对象,每次复制其实都是new了新对象,故改变其值并不会改变return的结果。
17 楼 nalan 2014-03-13  
akinlong 写道
楼主第三个说法是不对的, 你这里返回的还是String对象,可以归为第一种,如果这里return的是基本类型的话,是不会返回finally里的赋值的,而是return try中的值,具体的原因是可以看class的字节码执行顺序

刚才测试了下,基本类型还是会返回finally中的return的值,所以说无论return出现在什么位置,一定是返回第一个出现的return,只不过在返回前,会查看该层有没有finally,如果有,则首先执行finally语句,在finally中也是一样,如果有return,就会用finally中的return替代外面的return,如此往复执行而已,并没有很大的异议。只不过要深入理解堆和栈内存,理解赋值符(=)左右的不同而已。
16 楼 LitterChop 2014-03-13  
nalan 写道
其实应该这样理解,finally总是在return之前执行,而return最终结果之前finally才开始执行,所如果return name+age,一定是先执行name+age,此时return指向name+age生成的结果,也就是return的指向地址不会再发生变化,如果是对象,可以修改对象的属性,但是return指向的地址并没有发生变化,如果return的是不可变对象(比如String),实际上是return与name都指向了同一个对象地址,而不是return指向了name这个变量,所以说在执行finally的时候,name发生了变化(实际上是name变量指向了一个新的对象),而return依然指向原来的对象。

学习了
15 楼 85977328 2014-03-13  
nalan 写道
其实应该这样理解,finally总是在return之前执行,而return最终结果之前finally才开始执行,所如果return name+age,一定是先执行name+age,此时return指向name+age生成的结果,也就是return的指向地址不会再发生变化,如果是对象,可以修改对象的属性,但是return指向的地址并没有发生变化,如果return的是不可变对象(比如String),实际上是return与name都指向了同一个对象地址,而不是return指向了name这个变量,所以说在执行finally的时候,name发生了变化(实际上是name变量指向了一个新的对象),而return依然指向原来的对象。

精辟,学习了。感谢帮忙梳理。这其实主要反馈出对面性对象和虚拟机运行原理的理解。
14 楼 85977328 2014-03-13  
rex0654335 写道
请问意义何在。

我这个文章,就是记录一下而已啦
没有特别的深入研究,如果有兴趣,大家可以讨论
就是一种兴趣爱好,没有啥意义不意义的
13 楼 nalan 2014-03-13  
其实应该这样理解,finally总是在return之前执行,而return最终结果之前finally才开始执行,所如果return name+age,一定是先执行name+age,此时return指向name+age生成的结果,也就是return的指向地址不会再发生变化,如果是对象,可以修改对象的属性,但是return指向的地址并没有发生变化,如果return的是不可变对象(比如String),实际上是return与name都指向了同一个对象地址,而不是return指向了name这个变量,所以说在执行finally的时候,name发生了变化(实际上是name变量指向了一个新的对象),而return依然指向原来的对象。
12 楼 m635674608 2014-03-12  
一句话就总结了。try 中的return 在finally后执行!
11 楼 rex0654335 2014-03-12  
请问意义何在。
10 楼 akinlong 2014-03-12  
akinlong 写道
楼主第三个说法是不对的, 你这里返回的还是String对象,可以归为第一种,如果这里return的是基本类型的话,是不会返回finally里的赋值的,而是return try中的值,具体的原因是可以看class的字节码执行顺序

好吧,这里的return是有效的
9 楼 akinlong 2014-03-12  
楼主第三个说法是不对的, 你这里返回的还是String对象,可以归为第一种,如果这里return的是基本类型的话,是不会返回finally里的赋值的,而是return try中的值,具体的原因是可以看class的字节码执行顺序
8 楼 LitterChop 2014-03-12  
为什么对象会被修改状态呢?
7 楼 85977328 2014-03-11  
已经更新了,感谢朋友们参与讨论交流~~
共同进步
6 楼 85977328 2014-03-11  
timer_yin 写道
简单解释为 try catch 中的return都会被finally中的return给覆盖

恩,谢谢分享,我整理一下
5 楼 85977328 2014-03-11  
weijs 写道
我测试了一下,如果finally中有return,则返回finally中赋的值

//返回 js
public String check2() throws Exception { 
        String name = "js";
        try { 
            return name; 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally { 
            name = "piaohailin"; 
//            return name;
        } 
        return name; 
    }
   
    //返回 xxx
public String check2() throws Exception { 
        String name = "js";
        try { 
            return name; 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally { 
            name = "xxx"; 
            return name;
        } 
//       return name; 
    }

谢谢共享,我整理到文章当中~~
忘记了finally中有return的情况
4 楼 weijs 2014-03-11  
我测试了一下,如果finally中有return,则返回finally中赋的值

//返回 js
public String check2() throws Exception { 
        String name = "js";
        try { 
            return name; 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally { 
            name = "piaohailin"; 
//            return name;
        } 
        return name; 
    }
   
    //返回 xxx
public String check2() throws Exception { 
        String name = "js";
        try { 
            return name; 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally { 
            name = "xxx"; 
            return name;
        } 
//       return name; 
    }
3 楼 timer_yin 2014-03-11  
85977328 写道
timer_yin 写道
简单解释为 try catch 中的return都会被finally中的return给覆盖

错了吧。不能覆盖的

int a = 0;
try{ 
   a = 1;
   return a; 
}catch(Exception e){ 
   a = 2;
   return a; 
}finally{ 
   a = 3;
   return a; 
}

finally会覆盖掉try catch中的a 最后返回3
2 楼 85977328 2014-03-11  
timer_yin 写道
简单解释为 try catch 中的return都会被finally中的return给覆盖

错了吧。不能覆盖的
1 楼 timer_yin 2014-03-11  
简单解释为 try catch 中的return都会被finally中的return给覆盖

相关推荐

    java 中finally语句块与return的执行关系

    Java 中 finally 语句块与 return 的执行关系 Java 中的 finally 语句块是用于保证无论出现什么情况,一定要执行的代码块。在 try-catch-finally 结构中,finally 语句块的执行顺序是非常重要的。下面我们来详细...

    try-finally-return-in-finally.rar_return

    综上所述,`try-finally` 结构结合`return`语句的使用是一个重要的编程概念,尤其在处理异常和资源释放时。正确理解和应用这一机制可以提高代码的稳定性和可读性。而针对大量嵌套括号的正则表达式,我们需要关注其...

    try-catch-finally-return-in-finally.rar_return

    在这个例子中,尽管 `try` 和 `catch` 都有 `return`,但最终的返回值由 `finally` 块的 `return` 决定。`finally` 块总是会被执行,即使在 `try` 或 `catch` 中已经有一个 `return` 语句,这使得我们可以确保无论...

    浅谈Java中return和finally的问题

    在Java编程语言中,`return` 语句和 `finally` 语句的相互作用是一个重要的概念,尤其是在处理异常处理时。`finally` 语句块通常用于确保某些代码无论是否发生异常都会被执行,而 `return` 语句用于提前结束方法并...

    Java finally语句到底是在return之前还是之后执行?

    3. 即使在`finally`块中也有`return`语句,`finally`块中的代码将被执行,然后返回值会被覆盖。这意味着`finally`块的`return`总是会覆盖`try`或`catch`块中的`return`。 现在让我们深入源码层面来进一步理解这个...

    try~catch~finally中关于return的问题

    在Java的异常机制中,如果finally中含有return语句,则try和catch中的return语句将会被JVM忽视

    浅析Python中return和finally共同挖的坑

    本文主要给大家介绍了在Python中return和finally共同存在的坑,以及填坑经验,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 初识 return 相信每一个用过Python函数的童鞋, 肯定会用过return...

    try、catch、finally、return 执行顺序.doc

    下面我们来详细讲解 try、catch、finally、return 执行顺序的规则和特点。 首先,我们需要了解 try、catch、finally 语句的基本用法。try 语句用于包装可能抛出异常的代码,catch 语句用于捕捉 try 语句中的异常,...

    Jungle68#-#[Java] try catch finally,try里有return,finally还执行么?1

    Condition 3: try中有异常,try-catch-finally里都没有return ,finally 之后有个returntry中有异常以后,根据

    Java中finally和return的关系实例解析

    Java中finally和return的关系实例解析 Java中finally和return的关系实例解析是Java编程语言中一个重要的知识点。finally语句是Java语言中的一种特殊语句,它用于释放资源、关闭文件、关闭网络连接等操作。return...

    Java的throw和return

    ### Java的throw和return 在Java编程语言中,`...综上所述,`throw`和`return`是Java中非常重要的控制流结构,它们与`finally`块之间有着紧密的联系。正确理解和运用这些概念对于编写健壮可靠的Java程序至关重要。

    Java语言finally语句详解,finally到底是在return之前还是之后执行.zip

    Java语言finally语句详解,finally到底是在return之前还是之后执行.zip

    Java中finally块执行与return关系深度剖析

    Java finally语句到底是在return之前还是之后执行?Java finally执行深度剖析,具体看这篇博文:http://blog.csdn.net/lanxuezaipiao/article/details/16922895,这是里面相关的源码,欢迎大家下载使用。

    关于Java中的try-catch-finally语句和return

     第二:finally里面不建议放return语句,根据需要,return语句可以放在try和catch里面和函数的后。可行的做法有四:  1、return语句只在函数后出现一次。  2、return语句仅在try和catch里面都出现。  3、...

    浅谈Java finally语句到底是在return之前还是之后执行(必看篇)

    通过实验和示例,我们可以证明 finally 语句是在 try 的 return 语句执行之后,return 返回之前执行的。 在下面的示例中,我们可以看到 finally 语句是在 try 的 return 语句执行之后,return 返回之前执行的。 ``...

    Java异常处理中同时有finally和return语句的执行问题

    在涉及finally和return语句时,Java有一些特定的行为规则。 首先,`finally`块中的代码总是会被执行,除非程序在执行到`finally`块之前就退出了JVM(例如通过`System.exit()`)。即使在`try`块或`catch`块中有`...

    finally结构的注意点(一)

    在本文中,我们将深入探讨 `finally` 的使用和一些需要注意的细节,尤其是与Java相关的知识点。 首先,`finally` 通常与 `try-catch` 结构一起使用。在 `try` 块中,我们执行可能会抛出异常的代码。如果发生异常,...

    try-catch-finally捕获异常

    try-catch-finally语句是Java语言中一种常用的异常处理机制,当程序在执行过程中出现异常时,可以使用try-catch-finally语句来捕获和处理异常。下面将详细介绍try-catch-finally语句的使用方法和注意事项。 一、try...

    关于Java中try finally return语句的执行顺序浅析

    关于Java中try finally return语句的执行顺序浅析是Java语言中一个重要的知识点,今天我们来探讨一下try finally return语句的执行顺序。 首先,需要了解的是finally语句块是否一定会执行的问题。很多人第一反应是...

Global site tag (gtag.js) - Google Analytics