这是内存泄漏还是误报?

dln*_*385 38 java eclipse warnings memory-leaks

这是我的代码:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到一个警告new Scanner(a)说(我正在使用jdk1.7.0_05进行编译.):

Resource leak: '<unassigned Closeable value>' is never closed.
Run Code Online (Sandbox Code Playgroud)

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

Fra*_* IV 60

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

  Scanner scanner = new Scanner(a);
  scanner.useDelimiter(",");
  scanner.close();
Run Code Online (Sandbox Code Playgroud)

  • 这是一个泄漏,如果useDelimiter的实现返回的不是"this"(它在当前实现中没有). (7认同)
  • 实际上,`useDelimiter`有一个错误的名称和界面.如果它被称为`setDelimiter`并且返回类型为`void`,就像其他类似的方法一样,它根本不会成为问题. (4认同)
  • 不,这不是泄漏,这是编译器无法正确检测到的. (2认同)

Ban*_*zen 11

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

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

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