45

这是我的代码:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;

public class temp {
    public static void main(String[] args) throws FileNotFoundException {
        BufferedReader a = new BufferedReader(new FileReader("a"));
        Scanner scanner = new Scanner(a).useDelimiter(",");
        scanner.close();
    }
}

我收到一条警告new Scanner(a)(我正在使用 jdk1.7.0_05 进行编译。):

Resource leak: '<unassigned Closeable value>' is never closed.

我做错了什么,或者这只是一个错误的警告?

4

4 回答 4

67

如果像这样拆分代码,警告会消失吗?

  Scanner scanner = new Scanner(a);
  scanner.useDelimiter(",");
  scanner.close();
于 2012-07-13T02:30:01.333 回答
13

是的,您的代码有潜在的(但不是真实的)内存泄漏。您将 的返回值分配给useDelimiter(a)局部变量scanner,但构造函数结果被丢弃。这就是您收到警告的原因。

实际上, 的返回值useDelimiter(a)与构造函数调用返回的对象完全相同,因此您的代码可以很好地关闭资源。但这是编译器/代码分析工具无法检测到的,因为它必须知道 useDelimiters 实现。

一个非常好的代码分析工具应该会向您显示一个额外的警告,因为您正在关闭一个尚未在此方法中打开的资源(useDelimiter 的返回值)。如果您将这两条消息放在一起,则症状对您来说可能更清楚。

于 2012-07-13T05:32:29.837 回答
1

你有没有尝试:

Scanner scanner = new Scanner(new BufferedReader(new FileReader("a"))).useDelimiter(",");

如果它不起作用,您必须添加a.close();

于 2012-07-13T07:07:24.787 回答
0

是什么给了你这个警告?大概它会发出警告,因为分配/关闭不是在 try/finally 块中完成的,这通常是一个坏主意(在这种特定情况下不是问题,因为唯一可以引发错误的是新的 FileReader 并且如果它抛出实际上没有分配任何资源 - 但这可以通过单个方法调用来改变..)

关闭扫描仪会关闭底层流(确切地说是任何实现自身的东西Closeable(是BufferedReader的),因此除此之外代码很好。

于 2012-07-13T02:33:44.793 回答