Warum gibt mir Eclipse im folgenden Code die Erwärmung "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();
Scanner
die Warnung geschlossen und stummgeschaltet, es wird jedoch auch geschlossen,System.in
was normalerweise nicht wünschenswert ist.System.in
normalerweise nicht wünschenswert ist. Das liegt daran, dass Sie nicht mehr daraus lesen können. I. e. Sie erhalten,java.util.NoSuchElementException: No line found
wenn Sie versuchen,(new Scanner(System.in)).nextLine()
zum Beispiel anzurufen .Wie andere bereits gesagt haben, müssen Sie bei E / A-Klassen "Schließen" aufrufen. Ich werde hinzufügen, dass dies ein ausgezeichneter Ort ist, um den Versuch zu nutzen - endlich ohne Fang zu blockieren, so:
Dies stellt sicher, dass Ihr Scanner immer geschlossen ist, und gewährleistet eine ordnungsgemäße Bereinigung der Ressourcen.
Entsprechend können Sie in Java 7 oder höher die Syntax "Try-with-Resources" verwenden:
quelle
Sie müssen
in.close()
in einemfinally
Block aufrufen , um sicherzustellen, dass es auftritt.Von der Eclipse - Dokumentation, hier ist , warum es Flags dieses besondere Problem ( Betonung von mir):
Vollständige Erklärung hier .
quelle
Es ist Ihnen zu sagen , dass Sie den Scanner Sie instanziiert schließen müssen auf
System.in
mitScanner.close()
. Normalerweise sollte jeder Leser geschlossen sein.Beachten Sie
System.in
, dass Sie beim Schließen nicht mehr lesen können. Sie können sich auch dieConsole
Klasse ansehen .quelle
System.console()
nicht verfügbar ist, wenn eine Anwendung über Eclipse ausgeführt wird. Dies kann während der Entwicklung problematisch sein.Wenn Sie JDK7 oder 8 verwenden, können Sie Try-Catch mit Ressourcen verwenden. Dadurch wird der Scanner automatisch geschlossen.
quelle
try
wie gezeigt verwenden und keinecatch
Klausel verwenden.Die obige Zeile ruft den Konstruktor der Scannerklasse mit dem Argument System.in auf und gibt einen Verweis auf das neu erstellte Objekt zurück.
Es ist mit einem Eingabestream verbunden, der mit der Tastatur verbunden ist, sodass Sie jetzt zur Laufzeit Benutzereingaben vornehmen können, um den erforderlichen Vorgang auszuführen.
So entfernen Sie den Speicherverlust -
quelle
Sie sollten in der Nähe Ihren Scanner , wenn Sie mit ihm fertig sind:
quelle
Durch Hinzufügen
private static Scanner in;
wird das Problem nicht wirklich behoben, sondern nur die Warnung gelöscht. Wenn Sie den Scanner statisch machen, bleibt er für immer geöffnet (oder bis die Klasse entladen wird, was fast "für immer" ist). Der Compiler gibt Ihnen keine Warnung mehr, da Sie ihm gesagt haben, "halten Sie 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.
quelle
Im Allgemeinen sollten Instanzen von Klassen, die sich mit E / A befassen, geschlossen werden, nachdem Sie mit ihnen fertig sind. Am Ende Ihres Codes können Sie also hinzufügen
in.close()
.quelle
Ich habe es behoben, indem ich mich als private statische Scanner-Klassenvariable deklariert habe. Ich bin mir nicht sicher, warum das behoben wurde, aber genau das hat Eclipse empfohlen.
quelle
Der Scanner sollte geschlossen sein. Es wird empfohlen, Readers, Streams ... und diese Art von Objekten zu schließen, um Ressourcen freizugeben und Speicherlecks zu vermeiden. und dies in einem finally-Block, um sicherzustellen, dass sie geschlossen sind, auch wenn beim Behandeln dieser Objekte eine Ausnahme auftritt.
quelle
scanner.close()
" sehen, aber diese Antwort hilft ihm wirklich zu verstehen, was los ist. + 1quelle
Scanner
Die Warnung wird geschlossen und geschlossen.quelle