Oracle Java文档,用于新的“尝试-使用-资源”展示了AutoCloseable正在try(...)中构造的所有示例
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
...
}这似乎是安全的,因为即使构造函数(相对于后续事件)已经获得了必须释放的资源,如果我们遇到异常,它们也会被释放。
但是,正如https://www.baeldung.com/java-try-with-resources所指出的,从Java9开始,我们可以有效地使用在try(...)之前初始化的最终资源
FileOutputStream fos = new FileOutputStream("output.txt");
try (fos) {
// do stuff
}在类似的Java-9之前,我看到:
CustomStreamLikeThing connection = new CustomStreamLikeThing("db_like_thing");
// ... do some stuff that may throw a RuntimeException
try (CustomStreamLikeThing connection2=connection) {
// do some more stuff
}这似乎是合法的,但同时在某种程度上削弱了这一概念:如果CustomStreamLikeThing获得了可关闭的资源,它们可能不会被释放。
是否有关于AutoCloseable的构造函数何时应该包含在try(...)中的指导方针,或者这是否是一个趣味问题(例如“将所有我认为可能引发异常的东西都包含进来”)?
发布于 2020-09-08 12:39:01
是否有关于AutoCloseable的构造函数何时应该包含在
try(...)中的指导方针,或者这是否是一个趣味问题(例如“将所有我认为可能引发异常的东西都包含进来”)?
编码的基本规则是:你是故意做任何事情的。这就要求您了解自己正在做什么,以及代码中的每一件“事情”都在做什么。
意思:如果你有一些东西需要“关闭”,那么常识就是:用资源来尝试。
但是,您是专门询问“对象创建”的微妙方面的。这应该进入try(),还是可以在此之前完成?!
要做到这一点:只要您的源代码在语义上做了正确的事情,就没有硬规则。因此,它可以归结为这两个方面:
try(fos)选项适用于java9。对于那些不需要修补旧产品的人来说,这很好。但是对于那些经常要把“相同的改变”贴在同一产品的不同版本上的人.这些人可能更喜欢可以合并到java8环境中的源代码。发布于 2020-09-08 12:27:43
如果可能的话,您应该始终使用使用试用式资源。
当您分配资源时,您应该确保资源在完成时总是被释放。“始终”通常意味着您应该使用try-finally,这样在资源分配之后发生的任何错误都不会阻止资源被释放。
这意味着,如果您不使用具有资源的尝试,那么您需要使用try-finally,那么为什么我说总是使用具有资源的尝试呢?
因为调用close()也可能失败,而使用资源进行尝试时,添加了一个特性,称为抑制异常。
如果您曾经对一个失败的close()调用的堆栈跟踪进行过诅咒,它已经取代了本应在“使用资源的尝试”块中抛出的异常,那么您就会知道这一点的重要性,所以您现在不知道到底是什么导致了这个问题。
抑制异常是一个通常被忽略的特性,但是当一个级联异常被close方法抛出时,它节省了很大的时间。仅就这一点而言,请始终使用“尝试与资源”。
副作用:与使用try-finally相比,使用资源的尝试代码更少,在处理资源时,您肯定应该使用这两种方法之一。
发布于 2020-09-08 12:02:57
当构造函数直接出现在try-with语句中时,如下所示:
try (MyCloseable c = new MyCloseable()) {
// do stuff with c
} catch (IOException e) {
// handle exception
}然后,在以下任何一个抛出异常时都会调用catch块:
close()-method.因此,当每个特殊情况都抛出一个IOException时,不可能有一个catch块。
然而,使用这样的代码,您可以更多地控制异常处理:
MyCloseable c;
try {
c = new MyCloseable();
} catch (IOException e) {
// handle constructor exception
}
try (c) {
// do stuff with c
} catch (IOException e) {
// handle exception from close() or try-body
}但是,在上面的示例中,对于try-body和close方法,仍然有一个catch块,并且不建议这样做:
// initialize c like in the second example
try (c) {
try {
// do stuff with c
} catch (IOException e) {
// handle try-body exception
}
} catch (IOException e) {
// handle close() exception
}https://stackoverflow.com/questions/63793265
复制相似问题