2012-09-20 55 views
60

为什么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(); 

回答

43

因为你不闭上你的扫描仪

in.close(); 
+28

这将关闭'Scanner'和沉默警告,但它也将关闭'System.in'其通常不期望的。 –

+0

@StuartCook +1。有些东西要留意。 – informatik01

+3

为什么我们需要关闭扫描仪? “资源泄漏”是什么意思? –

3

当你用它做你应该close您的扫描仪:一般

in.close(); 
2

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

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: ")); 
    ... 
} 
+2

请注意'System.console ()'在通过Eclipse运行应用程序时不可用,这在开发过程中可能很麻烦。 –

0

扫描仪应该关闭。关闭Readers,Streams ...以及这类对象来释放资源和避免内存泄漏是一个好习惯;并在finally块中这样做,以确保即使在处理这些对象时发生异常也会关闭它们。

+0

这个答案实际上有助于OP知道他为什么应该关闭这个东西。当然,他可以阅读文档并查看“'scanner.close()'”,但这个答案确实有助于他/她理解正在发生的事情。 + 1 – HyperNeutrino

36

正如其他人所说,你需要在IO类上调用'close'。我要补充一点,这是使用try的理想地点 - 终于没有catch块,像这样:

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

这可以确保您的扫描仪始终是闭合的,以保证适当的资源清理。由一个私人静态扫描仪类变量声明中

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

资源泄漏是什么意思,它会对我产生怎样的影响? –

+4

@Borat - “资源泄漏”意味着某些系统资源(通常是内存)不必要地丢失或浪费。通常这会在您开始在程序正常运行期间抛出OutOfMemoryErrors时影响您。 –

+0

谢谢eric。我知道你可以通过在无限循环中向自身添加一个字符串来导致错误。我不确定扫描仪如何导致该错误。 –

0
private static Scanner in; 

我固定它:

等价地,在Java 7或更高版本,可以使用“尝试与 - 资源”的语法。不知道为什么修复它,但这是日食推荐我做的。

+2

您将此警告消除,但创建了资源泄漏 – zacheusz

8

您需要拨打in.close(),在finally区块中确保其发生。

从Eclipse的文档,这里是为什么它标志这个特殊问题(强调矿):

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

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

...

编译器将标志[侵犯]与 “资源泄漏: '流' 永远不会关闭”。

完整说明here

1

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

HTH, Manfred。

3

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

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(); 
} 
0
in.close(); 
scannerObject.close(); 

它将关闭Scanner,关上了警告。

2
Scanner sc = new Scanner(System.in); 

//do stuff with sc 

sc.close();//write at end of code. 
3
// 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.