java为啥需要finally?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java为啥需要finally?相关的知识,希望对你有一定的参考价值。

try
System.out.println("I have a crush on u!");
throw new Exception("Exception.");
catch (Exception e)
System.out.println(e.getMessage());
finally


System.out.println("go on");
//既然不加finally这个“go on"也必将被打印出来,那么为什么需要finally呢?
那我把本要写在finally中的内容写到后面System.out.println("go on");不也是可以的吗?我在这个位置不也可以释放资源吗?无论是否出现异常不也要执行吗?

无论是否出现异常不也要执行吗?这句话是有问题的,有些异常如果不处理,也就不会继续下去了。即程序从catch里改变控制流,不会执行后面的语句。加了finally,可以保证即使因为异常,后面的代码不会被执行,但是finally里面的语句还是会执行,这样可以释放一些申请的资源~或者做一些其他工具,比如作profiling统计等。

你可以在catch里面加个return来模拟类似情况,看看后面的语句会不会执行?
看看finally子例程里面的语句会不会执行,以及他们的执行顺序...
参考技术A 你要不把释放资源代码写在finally语句块内,一旦try语句块内有异常的话,像System.out.println("go on");这种位置的语句将不会有执行的机会。finally语句块内的代码是不论有没有异常都会被执行的,conn.close()这种释放资源的代码要写在finally语句块内,否则有异常发生时,数据库连接将不会被关闭,还是一直处于打开的状态! 参考技术B finally和try、catch配套使用的,

举个例子吧 (伪代码)

try
执行 insert表;
conn.commit();
conn.close();
conn = null;
}catch
try
conn.rollback();
conn.close();
catch (Exception e)

finally
conn.close();

连接数据库,插入数据,
如果报错,则需要回滚数据,并且关闭数据库,
finally按照执行顺序,是最后执行的,当以上操作都没有关闭数据库连接,则执行finally。如果没有finally,很可能数据库连接释放不了。

需要注意:不要什么东西都写到finally,finally执行效率很低的。
参考技术C finally不是必须的语句 是无论是否有异常都会执行的语句.
你的go on打印出来了是因为程序在执行的过程中没有出现异常,如果出现了 在finally之外写的任何语句都是无效的.你的go on就打印不出来了
参考技术D 可用可不用,如果用,无论是否产生异常,都将执行他的内容。

为啥 Kotlin 类默认是 final 而不是 open?

【中文标题】为啥 Kotlin 类默认是 final 而不是 open?【英文标题】:Why are Kotlin classes final by default instead of open?为什么 Kotlin 类默认是 final 而不是 open? 【发布时间】:2019-01-11 18:47:18 【问题描述】:

文档告诉我们关于open注解的以下内容:

类上的 open 注解与 Java 的 final 相反:它 允许其他人从这个类继承。默认情况下,所有类 Kotlin 是final,对应Effective Java, 3rd Edition, 第 19 条:设计和记录继承或禁止继承。

我的课

class Foo //I can't inherit it
open class Bar //I can inherit it

默认保留所有类final的真正动机是什么?性能有什么提升吗?还是只是一种设计模式?为什么默认禁止open

【问题讨论】:

您应该阅读 Effective Java 项目。它描述了为继承设计一个类需要多少工作。 极度痛苦的工作量。记录您对子类的所有要求,以及您要求他们不要做的所有事情。构建至少 3 个单独的子类,以验证您的基类实际上是有用的(哦,您不能自己编写这些类;必须由其他人编写,因为您会作弊)。等等等等等等。 大多数类应该是最终的。扩展它们可能是个坏主意。 【参考方案1】:

对我来说有两个原因:

首先,Kotlin 从函数式编程世界中汲取了许多想法,并尽可能频繁地使用不变性来避免所有 known problems with mutation。

因此,默认情况下将每个类声明为“final”(至少对我而言)是相似的。

在运行时不能更改或更改类(使用反射之类的东西),这会使 Kotlin 编译器的安全检查无用。

所以如果你想“改变”一个类的默认实现,你必须明确地将它标记为打开。

我想到的第二个想法是继承经常被误用。 一些常见陷阱的例子解释了here

有“Favor composition over inheritance”原则作为更好设计的指导方针。因此,默认情况下将每个类声明为 final 会迫使开发人员至少停下来思考解决问题的替代方法,而不是出于错误的原因使用继承。

但只要没有 kotlin 开发者的官方声明,我只能给出一个固执己见的答案。

【讨论】:

【参考方案2】:

Kotlin 设计师只是想确保每个人都遵循良好的做法。

正如已经记录的那样,设计师遵循Joshua Bloch's Effective Java,其中在类和接口一章中谈到了其中一个原则

设计和记录继承或禁止它

它提倡在使用之前明确记录任何继承行为的想法。

假设我们有,

class Foo 

我们(即使是此代码的非作者) 确信此 class Foo 对任何扩展都是关闭的,并且没有随机类正在使用它,这也是通过查看它的签名。相比之下,Java 类则不能这样说,除非声明为 final,否则某些悬空子类仍然可以扩展它。

另一方面,

open class Foo

仅通过类签名,我们就知道这个类是开放的继承,并且可能有多个类覆盖它的行为。如您所见,此处明确记录了继承

【讨论】:

如果你是 S.O.L.I.D.人,这似乎是在面对Open for Extension的飞行。我发现期末课程非常令人沮丧,尤其是在图书馆中。如果存在错误或者您想扩展它们,这会使过程变得非常复杂。编写良好的库具有内置的可扩展性,但没有人知道未来会怎样或如何使用库。【参考方案3】:

在默认情况下使类 final 可以在运行时使用更少的内存。

【讨论】:

【参考方案4】:

我能想到的另一个原因是 final 使静态调度优化成为可能,这意味着它不需要进行方法表查找。

【讨论】:

以上是关于java为啥需要finally?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA,为啥final类不能被继承,如果定义为final的类该类里面成员变量不特殊说明则是final类还是非final

java中为啥用finally语句

JAVA接口中成员变量必须是final类型的,为啥

为啥 Java 8 接口方法中不允许使用“final”?

为啥 java.lang.Object 中的 finalize() 方法是“受保护的”?

为啥我们需要 Python 中的“finally”子句?