it-swarm.com.de

Ressourcenleck: 'in' wird niemals geschlossen

Warum gibt mir Eclipse im folgenden Code die Meldung "Ressourcenleck: 'in' wird nie geschlossen"?

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

Weil Sie Ihren Scanner nicht schließen

in.close();
54
nogard

Wie andere bereits gesagt haben, müssen Sie bei IO Klassen 'close' aufrufen. Ich füge hinzu, dass dies ein ausgezeichneter Ort ist, um den try - finally-Block ohne Fang wie folgt zu verwenden:

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

Dadurch wird sichergestellt, dass Ihr Scanner immer geschlossen ist und die ordnungsgemäße Bereinigung der Ressourcen gewährleistet ist.

Entsprechend können Sie in Java 7 oder höher) die Syntax "try-with-resources" verwenden:

try (Scanner in = new Scanner(System.in)) {
    ... 
}
44
Eric Lindauer

Sie müssen in.close() in einem finally -Block aufrufen, um sicherzustellen, dass es auftritt.

In der Eclipse-Dokumentation finden Sie warum dieses spezielle Problem ( Schwerpunkt meins):

Klassen, die das Interface implementieren Java.io.Closeable (seit JDK 1.5) und Java.lang.AutoCloseable (seit JDK 1.7) stellen externe Ressourcen dar, die mit der Methode close () geschlossen werden sollten, wenn sie nicht mehr benötigt werden.

Der Eclipse-Compiler Java kann analysieren, ob Code, der solche Typen verwendet, dieser Richtlinie entspricht.

...

Der Compiler markiert [Verstöße] mit "Ressourcenleck: 'Stream' wird niemals geschlossen".

Vollständige Erklärung hier .

8
Will

Sie werden darauf hingewiesen, dass Sie den auf System.in Instanziierten Scanner mit Scanner.close() schließen müssen. Normalerweise sollte jeder Leser geschlossen sein.

Beachten Sie, dass Sie beim Schließen von System.in Nicht mehr lesen können. Sie können sich auch die Klasse Console ansehen.

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

Wenn Sie JDK7 oder 8 verwenden, können Sie try-catch mit Ressourcen verwenden. Dadurch wird der Scanner automatisch geschlossen.

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

Sie sollten schließen Ihren Scanner, wenn Sie damit fertig sind:

in.close();
3
Dan W

das Hinzufügen von private static Scanner in; behebt das Problem nicht wirklich, sondern löscht nur die Warnung. Wenn Sie den Scanner statisch machen, bleibt er für immer geöffnet (oder bis die Klasse entladen wird, was beinahe "für immer" ist). Der Compiler warnt Sie nicht mehr, da Sie ihm gesagt haben "Lass es für immer offen". Aber das ist nicht das, was Sie wirklich wollten, da Sie Ressourcen schließen sollten, sobald Sie sie nicht mehr benötigen.

HTH, Manfred.

2
user2393042

Im Allgemeinen sollten Instanzen von Klassen, die sich mit E/A befassen, geschlossen werden, nachdem Sie damit fertig sind. Am Ende Ihres Codes können Sie also in.close() hinzufügen.

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

Scanner in= new Scanner(System.in);

die obige Zeile ruft den Konstruktor der Scanner-Klasse mit dem Argument System.in auf und gibt einen Verweis auf ein neu erstelltes Objekt zurück.

Es ist mit einem Eingabestream verbunden, der mit der Tastatur verbunden ist, sodass Sie zur Laufzeit Benutzereingaben vornehmen können, um den erforderlichen Vorgang auszuführen.

//Write piece of code 

So entfernen Sie den Speicherverlust:

in.close();//write at end of code.
2
Aashi
private static Scanner in;

Ich habe es behoben, indem ich es als private statische Scanner-Klassenvariable deklariert habe. Ich bin mir nicht sicher, warum das behoben wurde, aber genau das empfehle ich Eclipse.

2
zachdyer

Der Scanner sollte geschlossen sein. Es empfiehlt sich, Readers, Streams ... und diese Art von Objekten zu schließen, um Ressourcen freizugeben und Speicherverluste zu vermeiden. und dies in einem finally-Block, um sicherzustellen, dass sie geschlossen sind, auch wenn beim Behandeln dieser Objekte eine Ausnahme auftritt.

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

//do stuff with sc

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