Java незарегистрированное исключение - PullRequest
6 голосов
/ 19 января 2010

Во время изучения Java я часто сталкиваюсь с этой ошибкой. Это выглядит так:

Не зарегистрированное исключение java.io.FileNotFound исключение; должен быть пойман или объявлен брошенным.

java.io.FileNotFound - просто пример, я видел много разных. В данном конкретном случае код, вызывающий ошибку:

OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("myfile.pdf")));

Ошибка всегда исчезает, и код компилируется и запускается успешно, как только я помещаю инструкцию в блок try / catch. Иногда это достаточно хорошо для меня, но иногда нет.

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

Что еще важнее, иногда, когда я помещаю весь код в try / catch, он вообще не может работать. Например. в этом конкретном случае мне нужно out.close (); в finally {} block; но если приведенное выше утверждение находится внутри try {} , finally {} не "видит" out и, следовательно, не может его закрыть.

Моей первой идеей было импортировать java.io.FileNotFound; или другое соответствующее исключение, но это не помогло.

Ответы [ 2 ]

10 голосов
/ 19 января 2010

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

InputStream in = null;
try {
  in = new InputStream(...);
  // do stuff
} catch (IOException e) {
  // do whatever
} finally {
  if (in != null) {
    try {
      in.close();
    } catch (Exception e) {
    }
  }
}

Это уродливо? Конечно. Это многословно? Конечно. Java 7 сделает его немного лучше с блоками ARM, но до тех пор вы застряли с вышеупомянутым.

Вы также можете позволить вызывающей стороне обрабатывать исключения:

public void doStuff() throws IOException {
  InputStream in = new InputStream(...);
  // do stuff
  in.close();
}

хотя даже тогда close(), вероятно, следует заключить в блок finally.

Но приведенное выше объявление функции говорит, что этот метод может выдать IOException. Поскольку это проверенное исключение, вызывающей стороне этой функции потребуется catch (или объявить, чтобы вызывающая сторона могла с ней справиться и т. Д.).

2 голосов
/ 19 января 2010

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

Вы должны предпринять соответствующие действия в случае сбоя. Обычно обработка должна быть на другом уровне, чем то, где было выброшено исключение.

Ресурс должен быть обработан правильно, который принимает форму:

acquire();
try {
    use();
} finally {
    release();
}

Никогда не помещайте acquire() в блок try. Никогда не ставьте ничего между acquire() и try (кроме простого назначения). Не пытайтесь освободить несколько ресурсов в одном блоке finally.

Итак, у нас есть две разные проблемы. К сожалению, синтаксис Java смешивает их. Правильный способ написания такого кода:

try {
    final FileOutputStream rawOut = new FileOutputStream(file);
    try {
        OutputStream out = new BufferedOutputStream(rawOut);
        ...
        out.flush();
    } finally {
        rawOut.close();
    }
} catch (FileNotFoundException exc) {
    ...do something not being able to create file...
} catch (IOException exc) {
    ...handle create file but borked - oops...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...