Dlaczego Eclipse wyświetla ocieplający się komunikat „Wyciek zasobów:„ in ”nigdy nie jest zamknięty” w poniższym kodzie?
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
i wyciszenie ostrzeżenia, ale również zostanie zamknięte,System.in
co zwykle nie jest pożądane.System.in
jest zazwyczaj niepożądane. To dlatego, że nie będziesz w stanie ponownie z niego przeczytać. I. e. otrzymasz,java.util.NoSuchElementException: No line found
jeśli spróbujesz zadzwonić(new Scanner(System.in)).nextLine()
na przykład.Jak powiedzieli inni, na zajęciach IO musisz wywołać „zamknij”. Dodam, że to świetne miejsce na skorzystanie z try - na koniec blokuj bez haczyka, tak:
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(); } }
Zapewnia to, że skaner jest zawsze zamknięty, co gwarantuje prawidłowe czyszczenie zasobów.
Równoważnie w Javie 7 lub nowszym możesz użyć składni „try-with-resources”:
try (Scanner in = new Scanner(System.in)) { ... }
źródło
Musisz zadzwonić
in.close()
wfinally
bloku, aby się upewnić.Z dokumentacji Eclipse, oto dlaczego go flagi to szczególny problem ( podkreślenie moje):
Pełne wyjaśnienie tutaj .
źródło
Jest informacją, że trzeba zamknąć skaner, którego instancję na
System.in
zScanner.close()
. Zwykle każdy czytelnik powinien być zamknięty.Zwróć uwagę, że jeśli zamkniesz
System.in
, nie będziesz mógł ponownie z niego przeczytać. Możesz również przyjrzeć sięConsole
klasie.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: ")); ... }
źródło
System.console()
nie jest dostępne podczas uruchamiania aplikacji za pośrednictwem Eclipse, co może być kłopotliwe podczas programowania.Jeśli używasz JDK7 lub 8, możesz użyć try-catch z zasobami, co spowoduje automatyczne zamknięcie skanera.
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(); }
źródło
try
jak pokazano, i nie używaćcatch
klauzuli.// An InputStream which is typically connected to keyboard input of console programs Scanner in= new Scanner(System.in);
powyższa linia wywoła klasę Constructor of Scanner z argumentem System.in i zwróci referencję do nowo skonstruowanego obiektu.
Jest podłączony do strumienia wejściowego, który jest podłączony do klawiatury, więc teraz w czasie wykonywania możesz wziąć dane wejściowe użytkownika, aby wykonać wymaganą operację.
//Write piece of code
Aby usunąć wyciek pamięci -
in.close();//write at end of code.
źródło
Należy zamknąć Scanner kiedy jesteś z nim zrobić:
źródło
dodanie
private static Scanner in;
tak naprawdę nie rozwiązuje problemu, a jedynie usuwa ostrzeżenie. Uczynienie skanera statycznym oznacza, że pozostanie on otwarty na zawsze (lub do wyładowania klasy, co jest prawie „na zawsze”). Kompilator nie daje już żadnych ostrzeżeń, ponieważ powiedziałeś mu „zostaw to otwarte na zawsze”. Ale to nie jest to, czego naprawdę chciałeś, ponieważ powinieneś zamykać zasoby, gdy tylko nie będziesz ich już potrzebować.HTH, Manfred.
źródło
Generalnie instancje klas, które zajmują się we / wy, powinny być zamykane po ich zakończeniu. Więc na końcu kodu możesz dodać
in.close()
.źródło
private static Scanner in;
Naprawiłem to, deklarując jako prywatną zmienną statyczną klasy Scanner. Nie jestem pewien, dlaczego to naprawiło, ale to właśnie zalecało mi zaćmienie.
źródło
Skaner powinien być zamknięty. Dobrą praktyką jest zamykanie czytników, strumieni ... i tego rodzaju obiektów w celu zwolnienia zasobów i zapobiegania wyciekom pamięci; i robiąc to w bloku final, aby upewnić się, że są one zamknięte, nawet jeśli wystąpi wyjątek podczas obsługi tych obiektów.
źródło
scanner.close()
”, ale ta odpowiedź naprawdę pomaga mu zrozumieć, co się dzieje. + 1Okej, poważnie, przynajmniej w wielu przypadkach jest to faktycznie błąd. Pojawia się również w VS Code i jest to linter zauważający, że osiągnąłeś koniec otaczającego zakresu bez zamykania obiektu skanera, ale nie rozpoznając, że zamknięcie wszystkich otwartych deskryptorów plików jest częścią zakończenia procesu. Nie ma wycieku zasobów, ponieważ wszystkie zasoby są czyszczone po zakończeniu, a proces odchodzi, nie pozostawiając miejsca na przechowywanie zasobu.
źródło
Scanner sc = new Scanner(System.in); //do stuff with sc sc.close();//write at end of code.
źródło
Zamknie się
Scanner
i wyłączy ostrzeżenie.źródło