Java';try-catch-finally机制中的返回值
我刚刚遇到以下代码:Java';try-catch-finally机制中的返回值,java,coding-style,jvm,Java,Coding Style,Jvm,我刚刚遇到以下代码: public class TestFinally { public static void main(String[] args) { int returnValue = function(); System.out.println("Return value: " + returnValue); } public static int function() { try {
public class TestFinally {
public static void main(String[] args) {
int returnValue = function();
System.out.println("Return value: " + returnValue);
}
public static int function() {
try {
return 1;
} catch (Exception e){
return 2;
} finally{
return 3;
}
}
}
毫无疑问,运行此代码将产生“returnvalue:3”的输出
然而,我很好奇:
Vern实现取决于JVM,而且有许多JVM。您可以深入了解它最终是如何实现的,但这不是唯一的方法。就语言而言,重要的是行为
我不明白第二点——为什么
最终存在?它并不像您所建议的那样只是返回错误代码的一种方法。您根本不必从内部返回。该构造的存在是为了确保某种类型的清理代码在某段代码之后运行,不管它是如何终止的,无论是正常终止还是通过异常终止或返回终止。我在Java语言规范中找到的内容至少定义了代码段应返回3。当然,它没有提到JVM应该如何实现这一点,以及可以进行哪些可能的优化
第节规定:
如果try块的执行由于任何其他原因突然完成,则执行finally块。还有一个选择:
如果finally块正常完成,那么try语句由于原因R而突然完成
如果finally块由于原因S而突然完成,那么try语句由于原因S而突然完成(并且原因R被丢弃)
第14章的开头(更准确地说)说明了什么是正常和突然的完成。例如,具有给定值的返回是突然完成
因此,在这种情况下,finally
块突然完成(原因:返回具有给定值的
),因此try
将出于相同的原因突然完成(返回3)。这一点在美国也得到了证实
如果表达式的求值正常完成,并生成一个值V,那么return语句会突然完成,原因是返回值为V
FWIW,我收到一个关于函数的警告:
public static int function(){
try{
return 1;
}catch(Exception e){
return 2;
}finally{
return 3; //WARNING on this line
}
}
它告诉我“最终块不能正常完成”。不管怎样,我仍然得到3作为返回值
无论如何,如果我尝试另一个例子:
public class TestFinally {
public static void main(String[] args) {
int returnValue = function();
System.out.println("Return value: " + returnValue);
}
public static int function() {
try {
return 1;
}
catch (Exception e) {
return 2;
}
finally {
System.out.println("i don't know if this will get printed out.");
}
}
}
输出将是(显然)
我不知道JVM是如何实现它的,但最简单的方法(至少在概念上)是:
“try”中的返回值被推送到堆栈上
然后执行“finally”块
新的返回值被推送到堆栈上
函数退出,返回值从堆栈中弹出,因此忽略第一个值
确实是个很好的问题。完全解释了第439页=>
如果表达式的计算正常完成,则生成
值V,则return语句突然完成,原因是返回
具有值V.
前面的描述说的是“试图转移控制权”,而不仅仅是“转移控制权”
控件”,因为如果方法或构造函数中存在任何try语句(§14.20)
其try块或catch子句包含return语句,然后是any finally
这些try语句的子句将在
控件被转移到方法或构造函数的调用方突然完成一个
最后一个子句可能会中断由返回语句发起的控制权转移。至1:不知道,我也想知道。to 2.:finally可用于做认为绝对需要做的事情,例如关闭流。我认为异常比错误代码更好,因为你已经在方法签名中看到了可能出错的地方(没有阅读任何文档),而且对于编码人员来说,忽略它们是很困难的。好吧,我不能回答第一个问题,但第二个问题似乎很明显。finally子句用于清理(如关闭流),即使代码返回,也必须进行清理。然而,在finally子句中返回是一种糟糕的做法,只是不要这样做。我不认为你需要在finnaly块中更改返回值,但是为什么他们要另一方面允许你这样做呢?但这不是一个好的做法。谢谢大家的投入。是的,我意识到我发布的问题不是那么清楚。我已经编辑并澄清了这个问题。我很好奇是否有人见过这样的代码使用,即在try块中执行返回,在finally块中使用第二个返回来覆盖try块的返回值。有人见过这种用法吗?
i don't know if this will get printed out.
Return value: 1