«Правильная обработка исключений» немного расплывчата. Я согласен с утверждением @Rob Kennedy о том, что обработка исключений не подходит, если вы не знаете, почему возникло исключение и что с ним делать. В противном случае следует разрешить распространение исключения. Так, например:
void foo(String address) throws JoeException {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
// Ensure the connection is closed when finished.
// This happens whether an exception occurs or not.
connection.close();
}
}
Если вы хотите перехватить исключение только для его печати, вы можете сделать что-то вроде этого:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
connection.close();
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
Здесь есть тонкость, которую даже опытные программисты на Java могут упустить. Если при создании соединения возникает исключение, его не нужно закрывать. Если во время записи в соединение возникает исключение, оно требует закрытия ; таким образом, пункт finally
. Тем не менее, акт закрытия также может вызвать исключение. Если закрытие соединения вызывает исключение, только это исключение будет выдано оператором try
. Если предложение finally
было получено в результате операции writeLn
, вызвавшей исключение, исключение из вызова writeLn
будет фактически проигнорировано. Это, вероятно, не то, что вы хотите.
Вместо этого мы можем попробовать что-то уродливое, как это:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
boolean normalCompletion = false;
try {
connection.writeLn("Hello World!");
normalCompletion = true;
} finally {
if (normalCompletion) {
// The writeLn operation completed normally.
// Propagate an exception thrown by the close operation.
connection.close();
} else {
// The writeLn operation completed abruptly.
// Ignore an exception thrown by the close operation.
try {
connection.close();
} catch (JoeException e) {
/* empty */
}
}
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
Это выглядит (и является) синтаксически отвратительным, но показывает "правильную" обработку исключений для сортировки. Улучшение языка из Project Coin должно немного исправить это.