Java 我赢了';不要在finally-blcok中使用try-catch语句。(爪哇)
下面是一些java代码Java 我赢了';不要在finally-blcok中使用try-catch语句。(爪哇),java,stream,garbage-collection,connection,try-catch-finally,Java,Stream,Garbage Collection,Connection,Try Catch Finally,下面是一些java代码 public class SomeClass { private Connection connection; public SomeClass(Connection c) { connection = c; } public void someWork(){ Connection c; try { // do something } catch (Exception e) { // some except
public class SomeClass {
private Connection connection;
public SomeClass(Connection c) {
connection = c;
}
public void someWork(){
Connection c;
try {
// do something
} catch (Exception e) {
// some exception code
} finally {
if (conn != null){
try {c.close();} catch (Exception e) {}
}
}
}
}
但我不喜欢代码
if (conn != null){
try {c.close();} catch (Exception e) {}
}
所以我认为代码
...catch (Exception e) {
// some exception code
} finally {
c = null;
}
但我看到“流对象未被垃圾收集”
我不会在finally块中使用try-catch语句。
请给我另一种方法。只需创建一个静态实用程序方法:
private static void closeQuietly(final Connection conn)
{
if (conn == null)
return;
try {
conn.close();
} catch (WhateverException ignored) {
}
}
然后
但最终,您还是会在finally块中使用try/catch
请注意,捕获异常是一个坏主意。捕获由conn.close()
专门引发的异常。捕获Exception
意味着您还可以捕获所有RuntimeException
s;这是一件坏事(tm)
如果你使用番石榴,你也可以使用,这和上面的代码差不多。你也可以看看,这很有趣
最后(双关语):如果您使用Java 7,请改用try with resources语句(请参阅):
如果未关闭并设置为NULL,您可能会留下一个僵尸连接。让其他人来尝试捕获并使用
closequiety()
-方法之一(例如)应该正是您所需要的:
与InputStream.close()等效,但将忽略任何异常。这
通常在finally块中使用
从Java7开始,假设是这样的
try (Connection conn = DriverManager.getConnection(props)) {
...
}
Java 7之前
Connection conn = DriverManager.getConnection();
try {
...
} finally {
conn.close();
}
如果为空且未关闭,请确保所有方法始终获得新的打开连接。
您需要知道的唯一一件事是,任何时候获得连接时,都必须将其关闭(因此出现finally块),否则您可能会在应用程序中打开该连接,并最终耗尽可用的连接。另一个解决方法是删除方法中的所有捕获:
public void someWork() throws SQLException{
Connection c;
try {
// do something
} finally {
if (conn != null){
c.close();
}
}
}
然后在调用someWork
方法的主方法中的方法之外执行错误检查,或者将其包装到另一个方法中,在该方法中调用someWork()
:
这样,try或finally中抛出的错误将在一个SQLException中声明。您可能不喜欢该代码,但在这种情况下它是必要的。(尽管可以用@fge的
closequity
method这样的方法包装代码。)
但还有一个更基本的问题。在块中更改某些工作
以关闭连接不足以防止泄漏。。。在这种情况下
为什么?
考虑这一点:
SomeClass sc = new SomeClass(createConnection());
// do some stuff
sc.someWork();
Q1:如果在“Dosomething”代码中抛出异常,会发生什么
问题2:如果在创建/构造SomeClass
时引发异常,会发生什么情况?(注意:即使使用最简单的构造函数,这也是可能的。例如,new
操作可能会抛出OOME…)
答:连接对象已泄漏。。。在两个基地
修复方法是在try/catch/finally内或之前分配资源(例如连接对象);e、 g
Connection c = createConnection();
try {
// do something
} catch (SomeException e) {
// some exception code
} finally {
if (c != null){
try {c.close();} catch (SomeException e) {}
}
}
在Java 7中,您也可以这样编写:
try (Connection c = createConnection()) {
// do something
} catch (SomeException e) {
// some exception code
}
前提是连接
实现了自动关闭
接口。Java 7版本是一个更复杂的实现的“语法糖”,它负责检查null
,调用close()
,并智能地处理任何产生的异常。(JLS提供了“使用资源进行尝试”实际操作的详细信息。)
记录在案:
- 问题不在于垃圾收集。问题是需要关闭
连接
对象
- 分配
null
不会导致关闭对象。它甚至不会导致垃圾收集。充其量,它可以使对象符合垃圾收集的条件。。。在将来的一些GC运行中
- 捕获异常是一个非常糟糕的主意。请阅读以下内容:
你为什么不呢?说真的,我看不出有什么理由任意禁止嵌套在另一个内部的语言构造。更重要的是,为什么要忽略这个异常?每次我看到一个try-catch块吞下了一个异常,我都想哭。这只是在以后调试时让某人的生活变得困难。谢谢你提供的信息。我应该写我的环境。我使用JDK6。但我真的找不到任何理由为每种情况捕获异常。我通常使用Exception e
和e.printStackTrace()
然后它的工作原理是这样的java.sql.SQLException:ORA-00936:oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:138)
你真的认为这是一种不好的方式吗?我想我捕捉到了错误是什么,它在哪里。我要说的是,如果捕捉到异常
,也会捕捉到与您的应用程序无关的异常workflow@user2503993-那是不幸的。但是如果你打算使用一种过时的语言,你必须忍受它的局限性。学习“喜欢它”。@user2503993-还要注意(并告诉你的老板/客户)Java6已经下线了。没有更多的安全更新。。。除非他/他们签订Oracle Java支持合同。
SomeClass sc = new SomeClass(createConnection());
// do some stuff
sc.someWork();
Connection c = createConnection();
try {
// do something
} catch (SomeException e) {
// some exception code
} finally {
if (c != null){
try {c.close();} catch (SomeException e) {}
}
}
try (Connection c = createConnection()) {
// do something
} catch (SomeException e) {
// some exception code
}