我想在finally块中关闭我的流,但它抛出了一个IOException
,所以我似乎必须在我的finally
块中嵌套另一个try
块才能关闭流。这样做对吗?它看起来有点笨重。
这是代码:
public void read() {
try {
r = new BufferedReader(new InputStreamReader(address.openStream()));
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch (IOException readException) {
readException.printStackTrace();
} finally {
try {
if (r!=null) r.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
如果您使用的是Java 7,您可以使用try with resources语句:
try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) {
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException readException) {
readException.printStackTrace();
}
它看起来有点笨重。
是的。至少java7的资源尝试解决了这个问题。
在java7之前,您可以制作一个closeStream
函数来吞噬它:
public void closeStream(Closeable s){
try{
if(s!=null)s.close();
}catch(IOException e){
//Log or rethrow as unchecked (like RuntimException) ;)
}
}
或者试试。。。最后在尝试捕获中:
try{
BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()));
try{
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
}finally{
r.close();
}
}catch(IOException e){
e.printStackTrace();
}
它更详细,finally中的异常将在try中隐藏一个,但在语义上更接近Java 7中引入的资源的try。
在Java 7中,您可以执行以下操作。。。
try (BufferedReader r = new BufferedReader(...)){
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException e) {
//handle exception
}
- 在try块中声明变量需要它实现
AutoCloseable
- 在try块中声明变量也将其作用域限制为尝试阻止
- 当try块退出时,try块中声明的任何变量都将自动调用
close()
它被称为Try with resources语句。
是的,它笨重、丑陋且令人困惑。一种可能的解决方案是使用Commons IO,它提供了一种closeQuietly方法。
本页右侧的"相关"栏中有许多问题实际上是重复的,我建议您仔细阅读这些问题,以了解处理此问题的其他方法。
就像提到Commons IO库的答案一样,Google Guava Libraries对java.IO.Closeable有一个类似的助手方法。该类是com.Google.common.IO.Closeables。您要查找的函数类似于Commons IO:closeQuietly((。
或者你可以自己滚动来关闭一堆:Closeables.close(closeable1,closeable2,closeable3,…(:
import java.io.Closeable;
import java.util.HashMap;
import java.util.Map;
public class Closeables {
public Map<Closeable, Exception> close(Closeable... closeables) {
HashMap<Closeable, Exception> exceptions = null;
for (Closeable closeable : closeables) {
try {
if(closeable != null) closeable.close();
} catch (Exception e) {
if (exceptions == null) {
exceptions = new HashMap<Closeable, Exception>();
}
exceptions.put(closeable, e);
}
}
return exceptions;
}
}
这甚至会返回任何抛出的异常的映射,如果没有抛出则返回null。
您在finally中的方法是正确的。如果在finally块中调用的代码可能引发异常,请确保处理或记录它。永远不要让它从finally块冒出来。
在catch块中,您正在吞下异常-这是不正确的。
谢谢。。。
public void enumerateBar() throws SQLException {
Statement statement = null;
ResultSet resultSet = null;
Connection connection = getConnection();
try {
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM Bar");
// Use resultSet
}
finally {
try {
if (resultSet != null)
resultSet.close();
}
finally {
try {
if (statement != null)
statement.close();
}
finally {
connection.close();
}
}
}
}
private Connection getConnection() {
return null;
}
来源。这个样本对我很有用。
我在您的代码中注意到的第一件事是,如果您查看代码,代码中缺少花括号{}。此外,您需要将r
的值初始化为null
,因此首先需要将null值传递给对象,这样,如果您编写了条件,就可以进行not null
条件检查并关闭流。