资源泄漏:“in”永远不会closures

为什么Eclipse在下面的代码中给我“永远不会closures”的变暖“资源泄漏:”?

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(); 

因为你不closures你的扫描仪

 in.close(); 

正如其他人所说的,你需要在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(); } } 

这确保您的扫描仪总是closures,保证适当的资源清理。

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

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

你需要在finally块中调用in.close()来确保它的发生。

从Eclipse文档,这是为什么它标记这个特定的问题( 重点我):

实现接口java.io.Closeable (自JDK 1.5以来)和java.lang.AutoCloseable (自JDK 1.7以来)的类被视为表示外部资源,当不再需要时,它们应该使用close()方法closures。

Eclipse Java编译器能够分析使用这种types的代码是否遵守这个策略。

编译器将用“资源泄漏:”stream“永远不会closures”标记[违规]。

这里完整的解释。

它告诉你,你需要closuresScanner.close()System.in上实例化的Scanner。 通常每个读者都应该closures。

请注意,如果closuresSystem.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: ")); ... } 

完成后应closures扫描仪:

 in.close(); 

如果您使用的是JDK7或8,则可以使用try-catch和resources.This将自动closures扫描器。

 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 (eg, print the error message) ex.printStackTrace(); } 
 // An InputStream which is typically connected to keyboard input of console programs Scanner in= new Scanner(System.in); 

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

它连接到一个连接到键盘的inputstream,所以现在在运行时你可以采取用户input做必要的操作。

 //Write piece of code 

要消除内存泄漏 –

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

通常情况下,处理I / O的类的实例在完成后应该closures。 所以在你的代码结尾你可以添加in.close()

 Scanner sc = new Scanner(System.in); //do stuff with sc sc.close();//write at end of code. 

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

HTH,Manfred。

扫描仪应该closures。 closuresReaders,Streams …和这类对象来释放资源和避免内存泄漏是一个很好的做法。 并在finally块中这样做,以确保即使在处理这些对象时发生exception,它们也会closures。

 private static Scanner in; 

我通过声明一个私有的静态扫描器类variables来修复它。 不知道为什么解决这个问题,但这是日食推荐我做的。

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

它将closuresScanner并closures警告。