Java Try Catch finally 没有 Catch 的块
Posted
技术标签:
【中文标题】Java Try Catch finally 没有 Catch 的块【英文标题】:Java Try Catch Finally blocks without Catch 【发布时间】:2011-06-01 08:57:59 【问题描述】:我正在审查一些新代码。该程序只有一个 try 和一个 finally 块。由于 catch 块被排除在外,如果 try 块遇到异常或任何可抛出的东西,它是如何工作的?是直接进入finally块吗?
【问题讨论】:
Difference between try-finally and try-catch的可能重复 @mP 每个人都应该进行代码审查,并向他们提出问题是如何学习和改进。 【参考方案1】:如果 try 块中的任何代码可以抛出已检查异常,则它必须出现在方法签名的 throws 子句中。如果抛出未经检查的异常,它就会从方法中冒出来。
finally 块总是被执行,无论是否抛出异常。
【讨论】:
第一段不一定正确。 Try 块可以嵌套。任何未捕获的异常,无论是否未经检查,都会从方法中冒出。 Try 块可以嵌套,但我不建议这样做。我不会那样写代码。 @duffymo:“冒泡出方法”是什么意思? @Anand 只是一些用于“抛出异常”的非技术性语言。 不忽略;传递方法链。【参考方案2】:关于try
/finally
的一个小说明:finally 将永远执行,除非
System.exit()
被调用。
JVM 崩溃。
try
块永远不会结束(例如无限循环)。
【讨论】:
try.. catch throw .. finally..
怎么样?我认为 finally 不会被执行
在这种情况下 finally 仍然会被调用。只有原始异常丢失。
之前调用 System.exit() 最后也不会被执行。
@jyw 这就是我上面列表中第一项的意思。
我不得不说,这涵盖了所有的基础!【参考方案3】:
Java 语言规范(1) 描述了try-catch-finally
的执行方式。
没有捕获相当于没有捕获能够捕获给定的 Throwable。
如果 try 块的执行由于抛出值 V 而突然完成,则可以选择: 如果 V 的运行时类型可分配给 try 语句的任何 catch 子句的参数,那么…… … 如果 V 的运行时类型不可分配给 try 语句的任何 catch 子句的参数,则执行 finally 块。然后有一个选择: 如果 finally 块正常完成,则 try 语句会因为抛出值 V 而突然完成。 如果 finally 块由于原因 S 突然完成,则 try 语句由于原因 S 突然完成(并且值 V 的抛出被丢弃并被遗忘)。
(1)Execution of try-catch-finally
【讨论】:
【参考方案4】:内部 finally 在将异常抛出到外部块之前执行。
public class TryCatchFinally
public static void main(String[] args) throws Exception
try
System.out.println('A');
try
System.out.println('B');
throw new Exception("threw exception in B");
finally
System.out.println('X');
//any code here in the first try block
//is unreachable if an exception occurs in the second try block
catch(Exception e)
System.out.println('Y');
finally
System.out.println('Z');
结果
A
B
X
Y
Z
【讨论】:
添加一个“return;”在第一个“finally”块中,结果将打印 A、B、X、Z 而没有 Y。有人知道为什么吗?本质上,这个添加的“返回”会掩盖抛出的异常?【参考方案5】:finally块总是在try块结束后运行,无论try正常结束还是异常异常结束,呃,throwable。
如果 try 块中的任何代码抛出异常,则当前方法只需重新抛出(或继续抛出)相同的异常(在运行 finally 块之后)。
如果 finally 块抛出异常/错误/throwable,并且已经有一个待处理的 throwable,它会变得丑陋。坦率地说,我完全忘记了发生了什么(对于我多年前的认证而言)。我认为两个 throwable 都链接在一起,但是您必须做一些特殊的巫术(即 - 我必须查找的方法调用)才能在“最终”被吐出之前解决原始问题,呃,吐了。
顺便说一句,try/finally 对于资源管理来说是很常见的事情,因为 java 没有析构函数。
例如-
r = new LeakyThing();
try useResource( r);
finally r.release(); // close, destroy, etc
“最后”,还有一个提示:如果您确实费心放入一个 catch,要么捕获特定(预期的)可投掷子类,要么只捕获“Throwable”,不 em> “异常”,用于一般的包罗万象的错误陷阱。太多的问题,例如反射错误,抛出“错误”,而不是“异常”,并且这些问题将被任何“catch all”编码为:
catch ( Exception e) ... // doesn't really catch *all*, eh?
改为这样做:
catch ( Throwable t) ...
【讨论】:
查看下面 Carlos Heuberger 的回答,了解丑陋的部分。【参考方案6】:版本 7 之前的 Java 版本允许 try-catch-finally...
的这三种组合try - catch
try - catch - finally
try - finally
无论try
或/和catch
块中发生什么,finally
块将始终被执行。所以如果没有catch
块,这里就不会处理异常。
但是,您仍然需要在代码中的某处使用异常处理程序——当然,除非您希望您的应用程序完全崩溃。这取决于您的应用程序的架构,该处理程序的确切位置。
Java try 块后面必须跟 catch 或 finally 块。 对于每个 try 块,可以有零个或多个 catch 块,但只有一个 finally 块。 如果程序退出(通过调用 System.exit() 或通过导致导致进程中止的致命错误),将不会执行 finally 块。
【讨论】:
"before version 7 allow" 您是否暗示 Java 7 和 Java 8 不允许这三种组合?我怀疑这就是你的意思,但这就是你的回答所暗示的。 如果try块中有return语句,是否执行finally块? @Rahul 是的,最后会被调用。参考:***.com/questions/65035/… @Aaron - try-with-resource 的新语法,它在 try 关键字之后的括号内构造的任何内容上自动调用 .close()。 @Roboprog 你是对的,但是资源必须实现 Autocloseable 接口【参考方案7】:try 块是如何工作的 遇到异常或任何事情 可扔的
异常被抛出块外,就像在任何其他没有被捕获的情况下一样。
无论 try 块如何退出,finally 块都会执行——无论是否有任何 catch,无论是否有匹配的 catch。
catch 块和 finally 块是 try 块的正交部分。你可以有一个或两个。使用 Java 7,您将无法拥有这两者!
【讨论】:
【参考方案8】:你不试试那个程序吗?它将转到 finally 块并执行 finally 块,但是不会处理异常。但是,这个异常可以在 finally 块中被否决!
【讨论】:
【参考方案9】:finally 块在 try 块完成后执行。如果 try 块离开时抛出了一些东西,则执行 finally 块。
【讨论】:
【参考方案10】:在try
块中,我们编写可以引发异常的代码。
catch
块是我们处理异常的地方。
无论是否发生异常,finally
块都会一直执行。
现在如果我们有 try-finally 块而不是 try-catch-finally 块,那么异常将不会被处理,并且在 try 块而不是控制去 catch 块之后它将进入 finally 块。 当我们不想对异常做任何事情时,我们可以使用 try-finally 块。
【讨论】:
【参考方案11】:无论try
块中是否抛出异常 - finally
块都将被执行。异常不会被捕获。
【讨论】:
以上是关于Java Try Catch finally 没有 Catch 的块的主要内容,如果未能解决你的问题,请参考以下文章
Java 在try—catch块之后的finally是干啥的?
为啥“catch”或“finally”范围内的“try”中没有声明变量?
请简述JAVA中 try-catch-finally 语句的执行过程 简单明了 好的话 加分(曹苇提问)