Подтвердить что ты не робот

Это утечка памяти или ложный позитив?

Это мой код:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;

public class temp {
    public static void main(String[] args) throws FileNotFoundException {
        BufferedReader a = new BufferedReader(new FileReader("a"));
        Scanner scanner = new Scanner(a).useDelimiter(",");
        scanner.close();
    }
}

Я получаю предупреждение в new Scanner(a), который говорит (я компилирую с помощью jdk1.7.0_05.):

Resource leak: '<unassigned Closeable value>' is never closed.

Я что-то делаю неправильно, или это просто ложное предупреждение?

4b9b3361

Ответ 1

Если вы разделите код следующим образом, будет ли предупреждение уходить?

  Scanner scanner = new Scanner(a);
  scanner.useDelimiter(",");
  scanner.close();

Ответ 2

Да, ваш код имеет потенциальную (но не реальную) утечку памяти. Вы присваиваете возвращаемое значение useDelimiter(a) локальной переменной scanner, но результат конструктора выбрасывается. Вот почему вы получаете предупреждение.

На практике возвращаемое значение useDelimiter(a) - это точно тот же объект, что и возвращаемый из вызова конструктора, поэтому ваш код просто отлично закрывает ресурс. Но это то, что инструмент анализа компилятора/кода не может обнаружить, поскольку он должен был бы знать реализацию useDelimiters для этого.

И действительно хороший инструмент анализа кода должен был показать вам дополнительное предупреждение, потому что вы закрываете ресурс, который не был открыт в этом методе (возвращаемое значение useDelimiter). Если бы у вас были эти 2 сообщения вместе, симптомы могли бы быть более понятны вам.

Ответ 3

Попробуйте:

Scanner scanner = new Scanner(new BufferedReader(new FileReader("a"))).useDelimiter(",");

Если это не сработает, вы должны добавить a.close();

Ответ 4

Что дает вам это предупреждение? Предположительно он предупреждает, потому что выделение/закрытие не выполняется в блоке try/finally, что, как правило, плохое (в данном конкретном случае это не проблема, потому что единственное, что может вызвать ошибку, это новый FileReader, и если это ни один ресурс не был выделен - но это может измениться с помощью одного вызова метода.)

Закрытие сканера закрывает базовый поток (точнее, все, что реализует себя Closeable (да BufferedReader), поэтому код отлично от него.