web-dev-qa-db-ja.com

リソースリーク:「in」が閉じられることはありません

次のコードで、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();
75
user1686995

スキャナーを閉じないため

in.close();
54
nogard

他の人が言ったように、IOクラスで 'close'を呼び出す必要があります。私はこれがtryを使用するのに最適な場所であることを追加します-最後にキャッチなしでブロックします:

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)) {
    ... 
}
45
Eric Lindauer

確実に発生させるには、finallyブロックでin.close()を呼び出す必要があります。

Eclipseのドキュメントから、whyこの特定の問題にフラグを立てる(emphasis鉱山):

インターフェイスを実装するクラスJava.io.Closeable(JDK 1.5以降)およびJava.lang.AutoCloseable(JDK 1.7以降)は外部リソースを表すと見なされます。外部リソースは、不要になったらclose()メソッドを使用して閉じる必要があります。

Eclipse Javaコンパイラーは、そのようなタイプを使用するコードがこのポリシーに準拠しているかどうかを分析できます。

...

コンパイラは、[リソースリーク: 'ストリーム'が閉じられない]というフラグを[違反]に付けます。

完全な説明 こちら

8
Will

Scanner.close()を使用して、System.inでインスタンス化したスキャナーを閉じる必要があることを伝えています。通常、すべてのリーダーを閉じる必要があります。

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: "));
    ...
}
6
Alex

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

close 完了したらスキャナーを使用する必要があります。

in.close();
3
Dan W

private static Scanner in;を追加しても問題は実際には修正されず、警告がクリアされるだけです。スキャナーを静的にすることは、永久に(またはクラスがアンロードされるまで(ほぼ「永久に」)オープンのままになることを意味します。あなたは彼に「それを永遠に開いておく」と言ったので、コンパイラはもう警告を与えません。ただし、リソースが不要になったらすぐにリソースを閉じる必要があるため、これは本当に望んでいたことではありません。

HTH、マンフレッド。

2
user2393042

一般に、I/Oを処理するクラスのインスタンスは、それらの処理が終了した後に閉じる必要があります。したがって、コードの最後にin.close()を追加できます。

2
arshajii
// 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.
2
Aashi
private static Scanner in;

プライベートの静的Scannerクラス変数として宣言することで修正しました。なぜそれが修正されたのかはわかりませんが、それがEclipseが私が推奨したことです。

2
zachdyer

スキャナーを閉じてください。 Readers、Streams ...、およびこの種のオブジェクトを閉じて、リソースとaovidメモリリークを解放することをお勧めします。そして、これらのオブジェクトの処理中に例外が発生した場合でも、それらが閉じられるように、finallyブロックでそうします。

1
Carlos Cambón
Scanner sc = new Scanner(System.in);

//do stuff with sc

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