Почему я должен создавать inputStream и outputStream с типом FileReader / Writer при создании самих объектов? - PullRequest
0 голосов
/ 07 декабря 2011

Хорошо, это код, и мой вопрос, почему я должен поставить FileReader inputstream = null; и то же самое с FileWriter.Почему я не могу просто создать объекты позже в блоке try?Я что-то упускаю ... Я, наверное, так.

public static void main(String[] args) throws IOException{
    // TODO Auto-generated method stub
        FileReader inputStream = null;
        FileWriter outputStream = null;
        try {
            inputStream = new FileReader("In.txt");
            outputStream = new FileWriter("Out.txt");
            int c;
            while ((c = inputStream.read()) != -1){
                outputStream.write(c);

            }
        }
                finally {
                    if (inputStream != null){
                        inputStream.close();
                    }
                    if (outputStream != null){
                        outputStream.close();

                }
        }

Ответы [ 4 ]

2 голосов
/ 07 декабря 2011

Поскольку вы не сможете ссылаться на них в блоке finally, и поэтому вы не сможете их закрыть.

Кстати, если они читают и пишут, вы 'Лучше называть переменные таким образом, чем xStream.

Обработка ввода-вывода всегда была утомительной, поэтому в Java 7 было введено "try with resource"

0 голосов
/ 08 декабря 2011

Я часто использую следующее

FileReader in = new FileReader("In.txt");
try {
    // do reading
} finally {
    in.close();
}

Это означает, что включающий метод генерирует IOException (т.е. FileNotFoundException).Это подходит и для Java 7:

try (FileReader in = new FileReader("In.txt"); FileWriter ...) {
    // do reading
}
0 голосов
/ 07 декабря 2011

Все дело в определенных правилах присваивания.Java позволит вам использовать локальную переменную только в том случае, если можно гарантировать, что переменная была инициализирована.

Рассмотрим эту упрощенную версию вашего кода:

    FileReader inputStream;  // not initialized here ...
    try {
        inputStream = new FileReader("In.txt");
        // do stuff
    } finally {
        if (inputStream != null) {
            inputStream.close();
        }
    }

Нет, предположим, что *Конструктор 1006 * не находит файл In.txt и выдает FileNotFoundException.Конструктор завершается «ненормально», и никакое значение не присваивается inputStream.Затем мы приходим к блоку finally, где мы пытаемся проверить, что inputStream не является null.Но в этот момент inputStream все еще неинициализирован, и Java не позволит нам принять значение неинициализированной локальной переменной, и вы получите ошибку компиляции.

На вид бесполезное присвоение null дляinputStream решает проблему, гарантируя, что переменная всегда инициализировалась, когда мы попадаем в блок finally.


Спецификация языка Java посвящает целую главу указанию правил определенного присваивания;то есть правила, которые использует компилятор, чтобы решить, была ли переменная инициализирована в любой данной точке.Эти правила довольно консервативны, и в некоторых случаях компилятор скажет, что что-то определенно не назначено, когда человек с большим умом может сделать вывод, что это так.Вы просто должны с этим смириться и иногда добавлять ненужную инициализацию или оператор return, который никогда не может быть выполнен.

0 голосов
/ 07 декабря 2011

Потому что с FileReader inputstream = null вы не создаете объект, просто ссылка с именем inputStream на один. Который из? Нет, ссылка инициализируется нулем. Позже вы можете или не можете создать объект (но что произойдет, если new FileReader(...) выдает исключение?); проверки в блоке finally должны работать с инициализированными переменными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...