Bạn chắc chắn không muốn có ba khối riêng biệt với mã như vậy. Trong khối đầu tiên, bạn đang gặp phải lỗi thiết lập writer
, nhưng sau đó trong các khối tiếp theo, bạn đang sử dụngwriter
, điều này không có ý nghĩa nếu khối đầu tiên không thành công. Bạn sẽ kết thúc việc ném NullPointerException
khi xảy ra lỗi I/O — không lý tưởng. :-)
Có rất nhiều chỗ cho phong cách trong công cụ này, nhưng đây là một sự diễn giải lại khá chuẩn của chức năng của bạn. Nó chỉ sử dụng hai khối (mặc dù bạn có thể chọn để thêm lại một phần ba, xem các chú thích trong code):
public void save(Object object, File file) {
BufferedWriter writter = null;
try {
writter = new BufferedWriter(new FileWriter(file));
Dictionary dictionary = (Dictionary)object;
ArrayList<Card> cardList = dictionary.getCardList();
for (Card card: cardList) {
String line = card.getForeignWord() + "/" + card.getNativeWord();
writter.write(line); // <== I removed the block around this, on
// the assumption that if writing one card fails,
// you want the whole operation to fail. If you
// just want to ignore it, you would put back
// the block.
}
writter.flush(); // <== This is unnecessary, `close` will flush
writter.close();
writter = null; // <== null `writter` when done with it, as a flag
} catch (IOException e) {
e.printStackTrace(); // <== Usually want to do something more useful with this
} finally {
// Handle the case where something failed that you *didn't* catch
if (writter != null) {
try {
writter.close();
writter = null;
} catch (Exception e2) {
}
}
}
}
Lưu ý về khối finally
: Ở đây, bạn có thể xử lý các trường hợp bình thường (trong trường hợp này writter
sẽ là null
) hoặc bạn có thể đang xử lý ngoại lệ mà bạn không nắm bắt (điều này không phải là bất thường, một trong những điểm ngoại lệ chính là xử lý những gì phù hợp ở cấp này và chuyển bất kỳ thứ gì khác cho người gọi) . Nếu writter
là !null
, hãy đóng. Và khi bạn đóng cửa sổ, hãy ăn bất kỳ ngoại lệ nào xảy ra hoặc bạn sẽ làm mờ sự cố ban đầu. (Tôi có các chức năng tiện ích để đóng mọi thứ trong khi ăn một ngoại lệ, cho chính xác tình huống này. Đối với tôi, điều đó có thể là writter = Utils.silentClose(writter);
[silentClose
luôn trả về null
]). Bây giờ, trong mã này bạn có thể không mong đợi các ngoại lệ khác, nhưng A) Bạn có thể thay đổi điều đó sau, và B) RuntimeException
s có thể xảy ra tại bất kỳ thời điểm nào. Tốt nhất để quen với việc sử dụng mẫu.
Nguồn
2010-11-14 12:14:19
Cảm ơn bạn đã giải thích tốt như vậy. – Eugene
@AndroidNoob: Đừng lo! Vui mừng đã giúp. –
@ T.J. Crowder tại sao bạn đóng 'writer' bên trong' try' block? Không phải là nó thừa? –