закрыть, деструктор и завершить: противоречия Java

У меня есть следующий код, который прекрасно работает в моем классе, читая файл построчно.

 try {  FileInputStream in = new FileInputStream(filename);
        BufferedReader reader=new BufferedReader(new InputStreamReader(in));
        String line;
        while((line=reader.readLine())!=null){
             // read the file
        }
    }
    catch (Exception e) {
        System.out.println(e);
    }

Но если я попытаюсь добавить команду close, ибо после того, как файл закончил чтение, то я получаю ошибку:

    in.close();

Error:(131, 9) java: cannot find symbol
symbol:   variable in
location: class ReadFile

Я искал об очистке объектов после использования и необходимости закрывать файлы до завершения вашей программы. И нашел несколько сообщений об этом для Java, но многие из них очень противоречивы. Дело в том, что в конце концов я просто очень запутался.

Я ошибаюсь, или программирование на Java немного нечеткое и запутанное? Я имею в виду, что, по-видимому, нет реального использования деструктора, использование finalize очень сомнительно, и использование close также предлагается как ненужный. Некоторые из сообщений по этим вопросам противоречивы и неубедительны.

Итак, как действовать здесь? В случае, если мне действительно нужно закрыть файл, как избавиться от этого сообщения об ошибке? Действительно ли закрытие файлов является необязательным и ненужным? Как насчет очистки экземпляров класса для завершения программы?


person Emma Yazzie    schedule 08.05.2014    source источник
comment
Куда вы звоните in.close()? Помните, что в Java масштаб имеет значение.   -  person Pradeep Simha    schedule 08.05.2014
comment
@PradeepSimha - сразу после закрытия catch{}   -  person Emma Yazzie    schedule 08.05.2014
comment
Объявите in за пределами вашего блока try.   -  person Pradeep Simha    schedule 08.05.2014
comment
@Vash - это не дубликат, так как упомянутый вами пост не решает проблемы, которые я здесь цитирую, ни команда close   -  person Emma Yazzie    schedule 08.05.2014
comment
В Java нет деструктора. Метод finalize() действительно не то, что вы должны использовать или полагаться на него. И close() абсолютно необходимо вызвать. Используйте оператор try-with-resources и узнайте о переменные области видимости. Это понятие важно для каждого языка.   -  person JB Nizet    schedule 08.05.2014
comment
@PradeepSimha - это просто выдаст еще одну ошибку, если я последую вашему предложению.   -  person Emma Yazzie    schedule 08.05.2014
comment
Также, если у вас есть JDK 7, вы можете использовать оператор try-with-resources вместо того, чтобы писать уродливую попытку-поймать-наконец.   -  person Siyuan Ren    schedule 08.05.2014
comment
@EmmaYazzie Что это за ошибка?   -  person Pradeep Simha    schedule 08.05.2014
comment
@JBNizet, не каждый язык ... насколько я помню, у PostScript нет области видимости как таковой, хотя вы можете ее подделать, и я думаю не TeX тоже.   -  person dfeuer    schedule 08.05.2014
comment
@JBNizet - Спасибо! очень содержательные ваши комментарии. Я это очень ценю.   -  person Emma Yazzie    schedule 08.05.2014
comment
@dfeuer: хорошо. На почти языках :-)   -  person JB Nizet    schedule 08.05.2014


Ответы (3)


Вы получаете ошибку, потому что вы определили переменную in внутри блока try, поэтому она не видна в catch/finally/или где-либо за пределами этой попытки. Переместите объявление за пределы попытки:

Изменить это

try {  FileInputStream in = new FileInputStream(filename);

to

FileInputStream in = null;
try {  in = new FileInputStream(filename);
person Juned Ahsan    schedule 08.05.2014
comment
Не используйте комментарии, чтобы спорить о механике сайта. - person Flexo; 08.05.2014
comment
@JunedAhsan - это решило сообщение об ошибке. - person Emma Yazzie; 11.05.2014

вы можете закрыть in.close() из блока try, поэтому, очевидно, вы получите ошибку, потому что in определен в блоке try, который является локальным.

Лучше использовать попробовать с ресурсом, чтобы вам не нужно было закрывать вручную файловый поток

person SpringLearner    schedule 08.05.2014
comment
Спасибо. Использование try с ресурсом — хороший подход. - person Emma Yazzie; 11.05.2014
comment
@EmmaYazzie добро пожаловать - person SpringLearner; 11.05.2014

В идеале вы должны вызвать метод close() внутри блока finally после проверки null. А для этого нужно объявить переменную in вне блока try.

Вызов метода close() в блоке finally гарантирует, что он вызывается независимо от того, было ли выброшено исключение кодом в блоке try.

EDIT: Это когда вы используете Java 6 или более раннюю версию. Для Java 7 и выше вы можете использовать попробовать с ресурсом, как это было предложено @JqueryLearner.

person Kuldeep Jain    schedule 08.05.2014
comment
try-with-resources еще лучше. Легче сделать правильно и сложнее ошибиться, и я думаю, что могут быть и другие преимущества. - person dfeuer; 08.05.2014
comment
Я имел в виду это для Java 6 или более ранней версии. Отредактировал мой ответ. Спасибо - person Kuldeep Jain; 08.05.2014