请解释为什么异常出现在第一个程序中而不是第二个程序中。
1)在read方法中没有return语句
class Example
{
public static void read()
{
try
{
int i = 9/0;
}
finally
{
System.out.println("This proogram is giving exception");
}
}
public static void main(String[] fel)
{
read();
}
}
2)在读取方法中使用return语句
class Example
{
public static void read()
{
try
{
int i = 9/0;
}
finally
{
System.out.println("This proogram is not giving exception");
return;
}
}
public static void main(String[] fel)
{
read();
}
}
请添加适当的语言标签
java的可能吗? 请编辑您的问题并添加合适的语言标签。
请包括异常stacktrace
return语句将覆盖引发的异常。 不要将return语句放在finally块中。
原因是在Java语言规范规则中规定了try / finally块执行的规则。实质上
如果try块抛出异常E,并且最终正常完成,则总体try / finally抛出E
如果try块抛出E,但finally未能正常完成,则E会被忽略,并且由于try最终导致的总try / finally"突然完成"
显式的return被认为是突然的,而不是正常的完成,因此在示例2中,final内部的返回将掩盖try引发的被零除的异常。
因此,在第二个程序中,JVM不会停止运行吗?
最终不应该在内部使用分支语句(return,goto),因为执行此类语句会使最终之前执行的其他指令无效。
Java语言规范说:如果try块的执行由于任何其他原因R突然完成,那么将执行finally块,然后可以选择:
如果finally块正常完成,则try语句由于原因R突然完成。
如果final块由于原因S突然完成,则try语句由于原因S突然完成(并且原因R被丢弃)。
注意-在finally块内的return语句将导致在try或catch块中引发的任何异常都将被丢弃。
因此,在第二个程序中,JVM不会停止运行吗?
在这两种情况下,代码都抛出java.lang.ArithmeticException,但是finally中的return丢弃该异常,并且方法退出而没有将异常转发给调用方。
这就是为什么通常不应该在finally块中使用return的原因之一。
Java语言规范(8),try-finally和try-catch-finally的14.20.2执行中对此进行了描述:
If execution of the try block completes abruptly because of a throw of
a value V, then there is a choice:
... (some similar but for this case irrelevant rules left out)
If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the finally block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly because of a throw of the value V.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten).
您可以在JLS 14.1语句的正常完成和异常完成中找到突然完成和正常完成的定义。但是基本上return被认为是突然完成。