Я использую буферизированное устройство записи и мой код, окружает устройство записи наконец блок. Мой код похож на это.
...........
BufferedWriter theBufferedWriter = null;
try{
theBufferedWriter =.....
....
......
.....
} catch (IOException anException) {
....
} finally {
try {
theBufferedWriter.close();
} catch (IOException anException) {
anException.printStackTrace();
}
}
Я должен использовать выгоду попытки в коде уборки в наконец, поскольку theBufferedWriter мог бы также бросить IOException. Я не хочу выдавать это исключение к вызову methos. Действительно ли это - хорошая практика для использования выгоды попытки в наконец? Если не, какова альтернатива? Предложите.
С уважением, Hiral
Более удобный способ сделать это - использовать IOUtils.closeQuiety из Apache commons-io . Он сохраняет ваш код в чистоте и устраняет часть шаблонов, присущих Java.
Ваш код становится:
BufferedWriter theBufferedWriter = null;
try{
theBufferedWriter = ...
...
} catch (IOException anException) {
...
} finally {
IOUtils.closeQuietly(theBufferedWriter);
}
Намного красивее и выразительнее.
Все в порядке, но перед закрытием следует проверить, не является ли theBufferedWriter
нулевым.
Вы также можете:
BufferedWriter theBufferedWriter;
try {
theBufferedWriter = new ...
try {
...
} finally {
try {
theBufferedWriter.close();
} catch (IOException closeException) {
closeException.printStackTrace();
}
}
} catch (IOException anException) {
...
}
или:
BufferedWriter theBufferedWriter;
try {
theBufferedWriter = new ...
} catch (IOException createException) {
// do something with createException
return; // assuming we are in a method returning void
}
try {
...
} catch (IOException anException) {
...
// assuming we don't return here
}
try {
theBufferedWriter.close();
} catch (IOException closeException) {
closeException.printStackTrace();
}
, но в основном я выполняю такие операции (например, запись файла) в специальном методе и предпочитаю генерировать исключение / an Exception, чтобы вызывающий мог его обработать (например, запрашивая другой файл, остановка приложения, ...):
void someMethod(...) throws IOException {
BufferedWriter theBufferedWriter = new ...
try {
...
} catch (IOExcepption anException) {
try {
theBufferedWriter.close();
} catch (IOException closeException) {
closeException.printStackTrace();
// closeException is not thrown, anException represents the main/first problem
}
throw anException;
}
theBufferedWriter.close(); // throws the Exception, if any
}
Обратите внимание: английский не является моим первым и не вторым языком, любая помощь приветствуется
Или вы можете использовать Lombok и аннотацию @Cleanup
, и вам больше никогда не придется снова писать пробную ловушку внутри.
Обычно это делается так (обратите внимание, что вызывает исключение IOException
):
//Vanilly Java
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
Теперь с Lombok вы просто пишете @Cleanup
в потоках
import lombok.Cleanup;
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
Это то, с чем нам придется жить до Java 7 и Блоки ARM .
В версии до Java 7 я бы сказал, что то, что вы написали, является лучшим решением.
В Java 7 и далее у вас есть Автоматическое управление ресурсами, призванное упростить эти вещи. С помощью этой функции вы можете сделать
BufferedWriter theBufferedWriter = null;
try (BufferedWriter theBufferedWriter = ...) {
....
......
.....
} catch (IOException anException) {
....
}
Можно добавить try-catch в файл finally. Это инструмент, который делает то, что вы хотите. Однако я чувствую, что выброшенное IOException при закрытии достаточно необычно, чтобы я позволил ему подавить любое исключение в теле таким образом.
try {
BufferedWriter writer = .....
try {
.....
} finally {
writer.close();
}
} catch (IOException e) {
....
}