资源泄漏:'in'永远不会关闭

时间:2012-09-20 19:13:20

标签: java eclipse input resources memory-leaks

为什么Eclipse会让我变暖“资源泄漏:'in'永远不会关闭”以下代码?

public void readShapeData() {
        Scanner in = new Scanner(System.in);
        System.out.println("Enter the width of the Rectangle: ");
        width = in.nextDouble();
        System.out.println("Enter the height of the Rectangle: ");
        height = in.nextDouble();

14 个答案:

答案 0 :(得分:54)

因为您没有关闭扫描仪

in.close();

答案 1 :(得分:44)

正如其他人所说,你需要在IO类上调用'close'。我将补充一点,这是一个使用try - finally块的绝佳位置,没有捕获,如下所示:

public void readShapeData() throws IOException {
    Scanner in = new Scanner(System.in);
    try {
        System.out.println("Enter the width of the Rectangle: ");
        width = in.nextDouble();
        System.out.println("Enter the height of the Rectangle: ");
        height = in.nextDouble();
    } finally {
        in.close();
    }
}

这可确保您的扫描仪始终处于关闭状态,从而确保正确的资源清理。

同样,在Java 7或更高版本中,您可以使用“try-with-resources”语法:

try (Scanner in = new Scanner(System.in)) {
    ... 
}

答案 2 :(得分:8)

您需要在in.close()块中调用finally以确保其发生。

从Eclipse文档中,这里是为什么它标记了这个特定问题(强调我的):

  

实现接口 java.io.Closeable 的类(自JDK 1.5起)   和 java.lang.AutoCloseable (因为JDK 1.7)被认为是   表示外部资源,应使用方法关闭   close(),当它们不再需要时。

     

Eclipse Java编译器能够分析代码是否使用此类代码   类型符合此政策。

     

...

     

编译器会将[违规]标记为“资源泄漏:'流'永远不会关闭。”

完整解释here

答案 3 :(得分:6)

它告诉您,您需要使用System.in关闭在Scanner.close()上实例化的扫描器。通常每个读者都应该关闭。

请注意,如果您关闭System.in,则无法再次阅读。您还可以查看Console课程。

public void readShapeData() {
    Console console = System.console();
    double width = Double.parseDouble(console.readLine("Enter the width of the Rectangle: "));
    double height = Double.parseDouble(console.readLine("Enter the height of the Rectangle: "));
    ...
}

答案 4 :(得分:4)

如果您使用的是JDK7或8,则可以将try-catch与资源一起使用。这将自动关闭扫描仪。

try ( Scanner scanner = new Scanner(System.in); )
  {
    System.out.println("Enter the width of the Rectangle: ");
    width = scanner.nextDouble();
    System.out.println("Enter the height of the Rectangle: ");
    height = scanner.nextDouble();
  }
catch(Exception ex)
{
    //exception handling...do something (e.g., print the error message)
    ex.printStackTrace();
}

答案 5 :(得分:3)

完成后,您应该close扫描仪:

in.close();

答案 6 :(得分:2)

通常,处理I / O的类的实例应在完成后关闭。因此,在代码的末尾,您可以添加in.close()

答案 7 :(得分:2)

private static Scanner in;

我通过将其声明为私有静态Scanner类变量来修复它。不知道为什么要修复它,但这就是eclipse推荐的。

答案 8 :(得分:2)

添加private static Scanner in;并没有真正解决问题,它只会清除警告。 使扫描仪静止意味着它永远保持打开状态(或直到课程被卸载,这几乎是“永远”)。 编译器不再给你任何警告,因为你告诉他“永远保持打开”。但这不是你真正想要的,因为一旦你不再需要它们就应该关闭资源。

HTH, 曼弗雷德。

答案 9 :(得分:2)

// An InputStream which is typically connected to keyboard input of console programs

Scanner in= new Scanner(System.in);

上面的行将使用参数System.in调用Scanner类的构造函数,并将返回对新构造的对象的引用。

它连接到连接到键盘的输入流,因此现在在运行时您可以使用用户输入来执行所需的操作。

//Write piece of code 

删除内存泄漏 -

in.close();//write at end of code.

答案 10 :(得分:1)

应关闭扫描仪。关闭读者,流......以及这类对象以释放资源和消除内存泄漏是一种很好的做法。并在finally块中执行此操作以确保即使在处理这些对象时发生异常也将其关闭。

答案 11 :(得分:1)

好的,至少在很多情况下,这实际上是一个错误。它也显示在VS Code中,这很容易引起注意,您已经到达了封闭范围的末尾而没有关闭扫描程序对象,但是没有意识到关闭所有打开的文件描述符是进程终止的一部分。没有资源泄漏,因为所有资源在终止时都会清理干净,并且过程消失了,资源也没有保留的地方。

答案 12 :(得分:0)

Scanner sc = new Scanner(System.in);

//do stuff with sc

sc.close();//write at end of code.

答案 13 :(得分:-1)

in.close();
scannerObject.close(); 

它将关闭Scanner并关闭警告。