Java序列化:在try或finally块中关闭流?
我在阅读Java序列化文章时,多次无意中发现流在try块而不是finally块中关闭的示例。有人能解释一下为什么会这样吗 例如:Java序列化:在try或finally块中关闭流?,java,serialization,inputstream,Java,Serialization,Inputstream,我在阅读Java序列化文章时,多次无意中发现流在try块而不是finally块中关闭的示例。有人能解释一下为什么会这样吗 例如: import java.io.*; public class DeserializeDemo { public static void main(String [] args) { Employee e = null; try { FileInputStream fileIn = new FileInputStrea
import java.io.*;
public class DeserializeDemo {
public static void main(String [] args) {
Employee e = null;
try {
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
} catch(IOException i) {
i.printStackTrace();
return;
} catch(ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
来源:您应该最终关闭连接。无论是尝试还是捕获,最终都将执行 我们还需要在每个连接创建后关闭它
try{
// statements
}catch (){
// statements
}
finally {
in.close();
fileIn.close();
}
从文件:
当try
块退出时,finally
块始终执行。这确保即使发生意外异常,也会执行finally块
运行时系统始终执行finally
块中的语句,而不管try
块中发生了什么。所以这是进行清理的最佳场所
所以,这意味着,如果您打开了一些连接、流或其他资源,那么您必须确保在执行代码块后它们将被关闭
要避免这种丑陋的块,可以使用实用程序方法:
public void close(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ex) {
// handle block
}
}
}
由于Java 8(但不是必需的),您可以为自己的异常处理程序提供关闭资源:
public void close(Closeable closeable, Consumer<? extends Throwable> handler) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ex) {
handler.accept(ex);
}
}
}
public void close(Closeable Closeable,Consumer您应该最终关闭block
在试区关门是个坏习惯
try {
e = (Employee) in.readObject(); //Possibility of exception
} catch(IOException i) {
} catch(ClassNotFoundException c) {
} finally {
in.close();
fileIn.close();
}
当某人在编写代码时知道它将抛出异常,他/她必须关闭打开的资源
try with resources语句
try with resources语句是一个try语句,用于声明一个或多个资源。资源是一个必须在程序完成后关闭的对象。try with resources语句确保在语句末尾关闭每个资源。实现java.lang.AutoCloseable的任何对象,包括所有对象实现java.io.Closeable的cts可以用作资源
下面的示例从文件中读取第一行。它使用BufferedReader的实例从文件中读取数据。BufferedReader是一种资源,在程序完成后必须关闭该资源:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
在本例中,try with resources语句中声明的资源是BufferedReader。该声明语句出现在try关键字后面的括号内。Java SE 7及更高版本中的BufferedReader类实现了接口Java.lang.AutoCloseable。因为BufferedReader实例是在try with语句中声明的-无论try语句是正常完成还是突然完成(由于方法BufferedReader.readLine引发IOException),它都将关闭
在Java SE 7之前,您可以使用finally块来确保资源关闭,而不管try语句是正常完成还是突然完成。以下示例使用finally块而不是try with resources语句:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
来源=>
我在阅读Java序列化文章时,多次无意中发现流在try块而不是finally块中关闭的示例
这样做的示例是糟糕的示例。关闭try
块中的流将适用于简单的一次性示例,但在可能多次执行代码的情况下这样做可能会导致资源泄漏
这个问题的其他答案很好地解释了关闭流的正确方法
有人能解释一下为什么会这样吗
这可以归结为教程网站的质量控制不佳,即代码审查不足。您应该始终在
最后块中关闭。
但是,您可以使用try with resources
以下是链接:
公认的答案肯定有缺陷
close方法也可以引发IOException
调用in.close时,异常会阻止fileIn.close获取
调用,并且fileIn流保持打开状态
当涉及多个流时,可按如下方式实现:
} finally {
if ( in != null) {
try { in .close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
}
if (fileIn != null) {
try {
fileIn.close();
} catch (IOException ex) {
// Again, there is nothing we can do if close fails
}
}
}
或者,利用可关闭的界面
} finally {
closeResource(in);
closeResource(fileIn);
}
方法:
private static void closeResource(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
}
}
如果您是Java 7或更高版本
不要在最后一个街区靠近
close方法可以抛出一个IOException
,并且FileInputStream
/ObjectInputStream
可以为null。当您在finally
中使用.close
时,您必须检查null并重试/catch
改用“try with resources语句”
使用代码如下所示:
try(
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)
) {
e = (Employee) in.readObject();
// in.close();
// fileIn.close();
}
try with resources语法保证资源实现接口将自动关闭。因此,您不需要对代码调用close
方法。这显然是一个错误的代码。如果引发IOException,流仍将打开。因为代码已损坏?对于我来说,当前正确的方法是使用try with-Resources
。是的,我注意到同一个教程网站上有很多错误。我建议您也/改为查看StackOverflow文档网站(请参阅本页顶部的“文档(beta)”按钮)。我们还有一些“质量控制问题”目前…但我们正在努力。哇,谢谢你的建议!我从来不知道有这样一件事:数据此代码肯定有错误。close方法也会引发IOException。如果在调用in.close时发生这种情况,则异常会阻止调用fileIn.close,fileIn流保持打开状态。
try(
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)
) {
e = (Employee) in.readObject();
// in.close();
// fileIn.close();
}