Я думал, что IOException и FileNotFoundException - именно такие исключения
Нет, на самом деле это "другие" типы исключений, которые выходят за рамки ваших навыков программирования. Независимо от того, насколько хорошо вы программируете, компилятор и библиотеки заставляют вас «осознавать», что что-то может произойти.
Подумайте об этом сценарии:
Вы создаете приложение, которое сохраняет данные во временную папку.
Все в порядке, вы проверили, что папка существует, а если нет, вы создаете ее самостоятельно.
А затем вы записываете 2 МБ в эту временную папку.
Внезапно другой системный процесс удаляет вашу временную папку, и вы больше не можете писать.
Вы ничего не можете сделать, чтобы предотвратить это программно, в некоторых системах такая операция может происходить (в unix пользователь root может выполнить команду rm -rf / tmp, и вы ничего не можете с этим поделать. В Windows я думаю, что система не позволит другому процессу удалить файл, который используется)
Заставив вас проверять подобные исключения в коде, дизайнеры платформы подумали, что, по крайней мере, вы об этом знаете.
Джон прав иногда вы ничего не можете с этим поделать, возможно, войдите в систему до того, как программа умрет, что считается «обработкой исключения» (плохая обработка да, но обработка по крайней мере)
try {
....
} catch( IOException ioe ) {
logger.severe(
String.format("Got ioe while writting file %s. Data was acquired using id = %d, the message is: %s",
fileName,
idWhereDataCame,
ioe.getMessage()) );
throw ioe;
}
Еще одна вещь, которую вы можете сделать, это «связать» исключение в соответствии с абстракцией.
Вероятно, ваше приложение имеет графический интерфейс, показывающий, что IOException для пользователя ничего не значит или может быть уязвимость безопасности . Модифицированное сообщение может быть отправлено.
try {
....
} catch( IOException ioe ) {
throw new EndUserException("The operation you've requeste could not be completed, please contact your administrator" , ioe );
}
И исключение EndUserException может быть захвачено где-то в графическом интерфейсе и представлено пользователю в диалоговом сообщении (вместо того, чтобы просто пропустить приложение в его глазах без дополнительной информации). Конечно, вы ничего не могли сделать, чтобы восстановить это IOException, но, по крайней мере, вы умрете со стилем: P
Наконец, клиентский код может использовать разные реализации, и не все исключения будут иметь смысл.
Например, подумайте еще раз о первом сценарии. Та же самая «операция» может иметь три вида «плагинов» для сохранения данных.
a) Write the data to a file.
b) Or, write to a db
c) Or write to a remote server.
Интерфейс не должен выбрасывать:
java.io.IOException
java.sql.SQLException
ни
java.net.UnknownHostException
Но вместо этого что-то вроде
my.application.DataNotSavedException
и различные реализации будут обрабатывать исключение на правильном уровне, и преобразуют его в соответствующую абстракцию:
Код клиента:
DataSaver saver = DataServer.getSaverFor("someKeyIdString");
try {
saver.save( myData );
} catch( DataNotSavedException dnse ) {
// Oh well... .
ShowEndUserError("Data could not be saved due to : " dnse.getMessage() );
}
Код реализации:
class ServerSaver implements DataSaver {
....
public void save( Data data ) throws DataNotSavedException {
// Connect the remore server.
try {
Socket socket = new Socket( this.remoteServer, this.remotePort );
OuputStream out = socket.getOut....
....
....
} catch ( UnknownHostException uhe ) {
// Oops....
throw new DataNotSavedException( uhe );
}
}
}
FileSaver и DatabaseSaver будут делать что-то похожее.
Все это Проверенные исключения , потому что компилятор заставляет вас проверять их.
Когда использовать один или другой (отмечен / не отмечен): здесь
Есть два других вида: здесь
И, наконец, гораздо более простое объяснение среды выполнения: здесь