Утечка ресурсов: "in" никогда не закрывается

Почему Eclipse дает мне утечку "утечка ресурсов" в "никогда не закрывается" в следующем коде?

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

Ответ 1

Поскольку вы не закрываете свой сканер

in.close();

Ответ 2

Как говорили другие, вам нужно вызвать "закрыть" на классах ввода-вывода. Я добавлю, что это отличное место для использования блока try-finally без 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();
    }
}

Это гарантирует, что ваш сканер всегда будет закрыт, что гарантирует правильную очистку ресурсов.

Эквивалентно, в Java 7 или более, вы можете использовать синтаксис "try-with-resources":

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

Ответ 3

Вам нужен вызов in.close() в блоке finally, чтобы убедиться, что он встречается.

В документации Eclipse, вот почему эта флага задает эту конкретную проблему (emphasis):

Классы, реализующие интерфейс java.io.Closeable (начиная с JDK 1.5) и java.lang.AutoCloseable (начиная с JDK 1.7) считаются представляют внешние ресурсы, которые должны быть закрыты с использованием метода close(), когда они больше не нужны.

Компилятор Eclipse Java способен анализировать, использует ли код такой типы придерживаются этой политики.

...

Компилятор отметит [нарушения] как "утечка ресурсов:" поток "никогда не закрывается".

Полное объяснение здесь.

Ответ 4

Сообщается, что вам нужно закрыть созданный вами сканер 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: "));
    ...
}

Ответ 5

Вы должны close ваш сканер, когда закончите с ним:

in.close();

Ответ 6

Если вы используете 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();
}

Ответ 7

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

Scanner in= new Scanner(System.in);

выше строка вызовет конструктор класса Scanner с аргументом System.in и вернет ссылку на вновь созданный объект.

Он подключен к входному потоку, который подключен к клавиатуре, поэтому теперь во время выполнения вы можете выполнить ввод пользователя для выполнения требуемой операции.

//Write piece of code 

Чтобы удалить утечку памяти -

in.close();//write at end of code.

Ответ 8

Как правило, экземпляры классов, которые имеют дело с I/O, должны быть закрыты после того, как вы закончите с ними. Поэтому в конце кода вы можете добавить in.close().

Ответ 9

Scanner sc = new Scanner(System.in);

//do stuff with sc

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

Ответ 10

добавление private static Scanner in; на самом деле не устраняет проблему, оно только очищает предупреждение. Создание статического сканера означает, что он остается открытым навсегда (или до тех пор, пока класс не будет разгружен, что почти "навсегда" ). Компилятор больше не предупреждает вас, так как вы сказали ему: "Держите его открытым навсегда". Но это не то, что вы действительно хотели, так как вы должны закрыть ресурсы, как только они вам больше не понадобятся.

НТН, Manfred.

Ответ 11

Сканер должен быть закрыт. Хорошая практика заключается в том, чтобы закрыть "Читатели", "Потоки"... и подобные объекты для освобождения ресурсов и утечек памяти aovid; и сделать это в блоке finally, чтобы убедиться, что они закрыты, даже если при обработке этих объектов возникает исключение.

Ответ 12

private static Scanner in;

Я исправил его, объявив в качестве частной переменной класса Scanner. Не уверен, почему это исправлено, но это то, что рекомендуется затмение.

Ответ 13

in.close();
scannerObject.close(); 

Он закроет Scanner и закроет предупреждение.