在Java 8中,Stream(它是AutoCloseable)不能重用,一旦它被使用或使用,流将被关闭。那么用try-with-resources声明来声明的效用是什么?声明Stream与try-with-resources声明之间有什么区别?
示例使用try-与资源声明:
public static void main(String[] args) throws IOException {
try (Stream<Path> entries
= Files.walk(Paths.get("."), 4, FileVisitOption.FOLLOW_LINKS)) {
entries.forEach(x -> System.out.println(x.toAbsolutePath()));// the entries stream will be automatically closed at this point
//..
System.out.println("Still in the Try Block");
} //The entries will be closed again because it is declared in the try-with-resources statement
}
这里没有try catch块
public static void main(String[] args) throws IOException {
Stream<Path> entries = Files.walk(Paths.get("."), 4, FileVisitOption.FOLLOW_LINKS);
entries.forEach(x -> System.out.println(x.toAbsolutePath()));// the entries stream will be automatically closed at this point
System.out.println("Is there a risk of resources leak ?");
}
哪一个更安全的相同的例子?
一些答案后,我更新我的代码检查,如果该流已关闭或不:
这里的新代码:
public static void main(String[] args) throws IOException {
resourceWithTry();
resourceWithoutTry();
}
private static void resourceWithTry() throws IOException {
try (Stream<Path> entries
= Files.walk(Paths.get("."), 4, FileVisitOption.FOLLOW_LINKS).onClose(() -> System.out.println("The Stream is closed"))) {
entries.forEach(x -> System.out.println(x.toAbsolutePath()));// the entries stream will be not automatically closed at this point
System.out.println("Still in the Try Block");
} //The entries will be closed again because it is declared in the try-with-resources statement
}
private static void resourceWithoutTry() throws IOException {
Stream<Path> entries
= Files.walk(Paths.get("."), 4, FileVisitOption.FOLLOW_LINKS).onClose(() -> System.out.println("Without Try: The Stream is closed"));
entries.forEach(x -> System.out.println(x.toAbsolutePath()));// the entries stream will be not automatically closed at this point
System.out.println("Still in the Try Block");
}
我更新了我的帖子,并且添加了一个新代码来检查流是否已关闭或未被占用,并且您有权利。谢谢 – Aguid
更准确地说,在这两种情况下(IO或集合流),在您的示例中的方法调用情况下,流实例将在方法返回后清除**(它并不真正专用于GC操作,方法调用在返回后丢弃的堆栈上工作)。无论在方法中抛出或不抛出异常,堆栈中的局部变量都被清除。 (1/2) – davidxxx
它们之间的区别在于使用资源(IO)的流将调用可能会锁定文件或维护连接等的方法....因此,在这种特定情况下,作为操纵资源返回的方法,你一定会清除这些可关闭资源上的所有可能的锁。(2/2) – davidxxx