Ответ 1
Поскольку вы не закрываете свой сканер
in.close();
Почему 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();
Поскольку вы не закрываете свой сканер
in.close();
Как говорили другие, вам нужно вызвать "закрыть" на классах ввода-вывода. Я добавлю, что это отличное место для использования блока 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)) {
...
}
Вам нужен вызов in.close()
в блоке finally
, чтобы убедиться, что он встречается.
В документации Eclipse, вот почему эта флага задает эту конкретную проблему (emphasis):
Классы, реализующие интерфейс java.io.Closeable (начиная с JDK 1.5) и java.lang.AutoCloseable (начиная с JDK 1.7) считаются представляют внешние ресурсы, которые должны быть закрыты с использованием метода close(), когда они больше не нужны.
Компилятор Eclipse Java способен анализировать, использует ли код такой типы придерживаются этой политики.
...
Компилятор отметит [нарушения] как "утечка ресурсов:" поток "никогда не закрывается".
Полное объяснение здесь.
Сообщается, что вам нужно закрыть созданный вами сканер 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: "));
...
}
Вы должны close ваш сканер, когда закончите с ним:
in.close();
Если вы используете 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();
}
// 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.
Как правило, экземпляры классов, которые имеют дело с I/O, должны быть закрыты после того, как вы закончите с ними. Поэтому в конце кода вы можете добавить in.close()
.
Scanner sc = new Scanner(System.in);
//do stuff with sc
sc.close();//write at end of code.
добавление private static Scanner in;
на самом деле не устраняет проблему, оно только очищает предупреждение.
Создание статического сканера означает, что он остается открытым навсегда (или до тех пор, пока класс не будет разгружен, что почти "навсегда" ).
Компилятор больше не предупреждает вас, так как вы сказали ему: "Держите его открытым навсегда". Но это не то, что вы действительно хотели, так как вы должны закрыть ресурсы, как только они вам больше не понадобятся.
НТН, Manfred.
Сканер должен быть закрыт. Хорошая практика заключается в том, чтобы закрыть "Читатели", "Потоки"... и подобные объекты для освобождения ресурсов и утечек памяти aovid; и сделать это в блоке finally, чтобы убедиться, что они закрыты, даже если при обработке этих объектов возникает исключение.
private static Scanner in;
Я исправил его, объявив в качестве частной переменной класса Scanner. Не уверен, почему это исправлено, но это то, что рекомендуется затмение.
in.close();
scannerObject.close();
Он закроет Scanner
и закроет предупреждение.