TRY里面有RETURN语句
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
java中异常处理中return的用法关于try、catch、finally语句块中含有return语句的几点说明:
1、第一种情况:try块有return语句,catch块没有return,函数末尾也没有return:
看代码:
import java.util.*;
public class demo{
public static void main(string args[]){
int num = 10;
test(num);
}
public static int test(int b){
try{
b += 10;
return b;
}catch(exception e){
}finally{
}
}
}
编译结果:
h:\java demo>javac demo.java
demo.java:18: 缺少返回语句
}
^
1 错误
有人可能会说,我在try块中不是有return语句吗?为什么会提示缺少return语句呢?这是因为编译器认为try块中是又可能产生异常操作
的,也就是说在return语句之前如果出现异常的话,那么return语句根本没有机会得到执行,所以编译器会认为缺少return语句。
解决办法:a、在catch块中加入return语句,因为一旦出现异常,catch中的语句可以保证函数会有一个返回值
b、在finally块中加入return语句,同样只要系统不退出,finally语句块会始终得到执行的
代码:
import java.util.*;
public class demo{
public static void main(string args[]){
int num = 10;
system.out.println(test(num));
}
public static int test(int b){
try{
b += 10;
return b;
}catch(exception e){
}finally{ return 0;
}
}
}
c、在函数末尾加入return语句
代码:
import java.util.*;
public class demo{
public static void main(string args[]){
int num = 10;
system.out.println(test(num));
}
public static int test(int b){ try{
b += 10;
return b;
}catch(exception e){
}finally{
}
return 0;
}
}
2、第二种情况,看代码:
import java.util.*;
public class demo{
public static void main(string args[]){
int num = 10;
system.out.println(test(num));
}
public static int test(int b){
try{
b += 10;
}
return 0;
}
}
结果:h:\java demo>javac demo.java
demo.java:8: try 不带有 catch 或 finally
try{
^
1 错误
说明:也就是说,如果有try语句的话,可以有catch语句,没有finally语句,但是如果没有catch语句的话,那么一定要有finally语句。
并且如果出现catch语句的话,catch语句可以出现多次,而finally语句只能出现
一次。
代码:
public class demo{
public static void main(string args[]){
int num = 10;
system.out.println(test(num));
}
public static int test(int b){ try{
b += 10;
}catch(runtimeexception e){
}catch(exception e2){
}finally{
}
return 0;
}
}
3、第三种情况:
a、try块中有return语句,那么是先执行return语句,还是先执行finally语句。
大家通常会有一个错误的认识,可能有的老师都会讲错
,认为是先执行finally语句,再执行return语句,但是这是错误的,事实上是先执行return语句,再执行finally语句,然后将结果返回,也可以说return语句执行了两次,一次在finally之前,一次在finally之后,但是返回的确是第一次执行的值,如果有不信的,请继续看代码,此段代码可以证明我的观点:
代码:
public class demo{
public static void main(string args[]){
int num = 10;
system.out.println(test(num));
}
public static int test(int b){
try{
b += 10;
return b;
}catch(runtimeexception e){
}catch(exception e2){ }finally{
b += 10;
}
return 0;
}
}
结果:
h:\java demo>javac demo.java
h:\java demo>java demo 20
说明:此处需要引入缓冲的概念,有对缓冲不太了解的也没关系,程序运行结果是20
足以证明我的观点,程序执行流程是进入try语句块
执行return语句,但是程序有finally语句块,所有先将return返回的值缓冲起来,然后程序跳转到finally语句块执行,我在finally语
句块中修改了变量b的值,但是程序返回的依然是20,并不是30,说明finally语句块执行完毕后,程序直接将之前缓冲的值返回了。
所以
这就是真实的执行流程。
b、try块中有return,finally语句块中也有return,此时的情况是什么样呢?看代码:
public class demo{
public static void main(string args[]){
int num = 10;
system.out.println(test(num));
}
public static int test(int b){
try{
b += 10;
return b;
}catch(runtimeexception e){
}catch(exception e2){
}finally{
b += 10;
return b;
}
} }
结果是:
h:\java demo>java demo
30
说明:为什么此时结果是30了呢,大家都知道return语句的作用是结束程序体,所以此段代码依然是先执行try块中的return语句,并将20
缓存起来,接着跳转到finally语句块执行,但是由于finally语句块中有return语句,所以程序在此处结束,并不返回到try块中返回结
果,而是直接将finally块中新修改的值即30,返回。
c、try块中有return语句,catch块中也有return语句,这时候是最简单的一种情况:
看代码:
public class demo{
public static void main(string args[]){
int num = 10;
system.out.println(test(num));
}
public static int test(int b){
try{
int a = b/0;
return b;
}catch(exception e2){
b += 10;
return b;
}
}
}
结果:
h:\java demo>java demo
20
说明:我在try块中触发了一个异常,程序跳入catch语句块,try语句块中剩篇二:try finally内有return的情况总结
「java」 try、finally语句块内有 return 的注意问题
情况一:(最普通用法)
public class test {
public static void main(string[] args) {
system.out.print(tt());
}
public static int tt() {
int b = 23;
try {
system.out.println(yes);
return b += 88;
} catch(exception e) {
system.out.println(error: + e);
} finally {
if (b > 25) {
system.out.println(b>25: + b);
}
system.out.println(finally);
}
return b;
}
}
输出(开始)
yes
b>25:111
finally
111
输出(结束)
结论1 :说明finally语句在return语句执行完了以后才执行的.
情况二:(finally中有return语句)
修finally部分
public static int tt() {
int b = 23;
try {
system.out.println(yes);
return b += 88;
} catch(exception e) {
system.out.println(error: + e);
} finally {
if (b > 25) {
system.out.println(b>25: + b);
}
system.out.println(finally);
return 100;
}
}
输出(开始)
yes
b>25:111
finally
100
输出(结束)
结论2:这样又说明了一个问题,finally语句块里面的return把原来的return给覆盖了,变成了新的返回值了.
情况三:(finally内改变返回值的value,但不返回)
继续修改
输出(开始)
yes
finally
23
输出(结束)
结论3:如果finally语句中没有返回语句覆盖的话,那么原来的返回值就不会变,不管你是不是改变了要返回的那个变量.
public static int tt() {} int b = 23; try {} return b; system.out.println(yes); return b; system.out.println(error: + e); if (b > 25) { } system.out.println(finally); b = 100; system.out.println(b>25: + b); } catch (exception e) { } finally {
情况四:(在try、finally外,返回一个值,会不会改变try、finally内的返回值)输出(开始)
yes
b>25 : 88
finally
88
输出(结束)
结论4 :如果try、finally内已经有return,则外部的return不会起作用。
总结:
碰到try语句中的return,那么先把return的值放在某个池中,然后执行finally里面的代码块, 如果有返回值覆盖语句,就改变先前放在池中的那个值;
如果没有,就把那个池中的东西取出来返回出去。
简单来说就是
---------对待try、finally内有return语句的情况,只有在finally覆盖return,才会改变返回值。
否则即使在最外层return新值,也不会改变原有的return值。
public static int tt() { int b = 23; try {system.out.println(yes);return b = 88; } catch(exception e) {system.out.println(error : + e); } finally {if (b > 25) { system.out.println(b>25 : + b);}system.out.println(finally); } return 100; }篇三:try语句
引子:
不管是在c++还是在java中,异常都被认为是一种很优雅的处理错误的机制,而如果想在c语言中使用异常就比较麻烦。
但是我们仍然可以使用c语言中强大的setjmp和longjmp 函数实现类似于c++的异常处理机制。
有关c语言中setjmp和longjmp的资料可以参考:
基本原理
结合setjmp,将当前的环境变量打包为frame(定义的一个结构名)压到一个异常堆栈(自定义的结构体)中,如果程序段正常运行,将此frame弹出,而如果程序出错,将异常栈的顶部元素弹出,根据这个栈顶元素的frame中保存的环境变量,通过setjmp将环境恢复,然后执行某个错误处理函数,而如果没有相应错误处理函数,重新弹出新的栈顶元素,以跳到更外层的setjmp块进行处理。
主要代码分析
此异常机制的实现大量应用了宏,以实现c++和java中异常处理的语法效果。
如何使用见下面的如何使用部分。
try部分,作用见注释:c 代码
1. //try的作用就是将一个包含环境变量env的except_frame压入
except_stack栈中。
2. //其中except_flag为setjmp的返回值,表示异常的状态
3. #define try do{ \
4. volatile int except_flag; \
5. except_frame except_frame; \
6. except_frame.prev = except_stack; \
7. except_stack = &except_frame; \
8. except_flag = setjmp(except_frame.env); \
9. if (except_flag == except_entered) \
10.{
最重要的部分要数except_raise函数,检查异常是否被处理,如果未被处理,重新从异常栈中弹出新的frame,以跳到更外层的异常处理块。
catch(e)也是宏,检查当前的frame是否和这个catch块中的e对应,如果对应的话,执行下面的部分进行处理。
因为所有except_frame全部放在栈上,因此可以说这个except_stack利用了程
序自动产生的stack机制,只要正确地改变except_stack的值就可以了,不必再考虑分配的except_frame的释放问题,空间的分配释放全由程序自动生成的stack管理。
如何使用
使用这个异常机制的代码,如下
c 代码
1. try{
2.s;
3. }catch(e1){
4.s1;
5. }catch(e2){
6.s2;
7. }else_catch{
8.s3;
9. }end_try;
此相当于c++中的:
1. try{
2. s;
3. }catch(e1){
4. s1;
5. }catch(e2){
6. s2;
7. }catch(…){
8. s3;
9. }
当前实现的异常机制也支持finally语句,因此下面的代码: c代码
1. try{
2. s;
3. }catch(e1){
4. s1;
5. }finally{
6. s2;
7. }end_try;
相当于java中的:
java 代码
1. try{
2. s;
3. }catch(e1except e1){
4. s1;
5. }finally
6. s2;
源代码
文件:exception.h
c 代码
1. #ifndef __exception_h__
2. #define __exception_h__
3.
4. #include <stdio.h></stdio.h>
5. #include <setjmp.h></setjmp.h>
6. #include <assert.h></assert.h>
7.
8.
9. #define t except_t
10.typedef struct except_t{
11. char *reason;
12.}except_t;
13.
14.typedef struct except_frame{
15. struct except_frame *prev;
16. jmp_buf env;
17. const char *file;
18. int line;
19. const t* exception;
20.}except_frame;
21.
22.extern except_frame *except_stack;//全局变量23.
24.//异常的状态常量
25.enum {except_entered=0,except_raised,
26. except_handled,except_finalized};
27.
28.#define throw(e) except_raise(&(e),__file__,__line__) 29.
30.#define rethrow except_raise(except_frame.exception,\
31. except_frame.file,except_frame.line) 32.
33.void abort_without_exception(const except_t *e,const char *file,int line);
34.
35.//将栈顶元素从栈中弹出,重新抛出
36.void except_raise(const t *e,const char *file,int line); 37.
38.//try的作用就是将一个包含环境变量env的except_frame压入except_stack栈中。