Bạn thực sự có thể mở rộng Consumer
(và Function
v.v.) bằng một giao diện mới xử lý các ngoại lệ - sử dụng các phương thức mặc định của Java 8 !
Xem xét giao diện này (mở rộng Consumer
):
@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {
@Override
default void accept(final T elem) {
try {
acceptThrows(elem);
} catch (final Exception e) {
// Implement your own exception handling logic here..
// For example:
System.out.println("handling an exception...");
// Or ...
throw new RuntimeException(e);
}
}
void acceptThrows(T elem) throws Exception;
}
Sau đó, ví dụ, nếu bạn có một danh sách:
final List<String> list = Arrays.asList("A", "B", "C");
Nếu bạn muốn sử dụng nó (ví dụ: với forEach
) với một số mã đưa ra các ngoại lệ, theo truyền thống, bạn sẽ thiết lập một khối thử / bắt:
final Consumer<String> consumer = aps -> {
try {
// maybe some other code here...
throw new Exception("asdas");
} catch (final Exception ex) {
System.out.println("handling an exception...");
}
};
list.forEach(consumer);
Nhưng với giao diện mới này, bạn có thể khởi tạo nó bằng biểu thức lambda và trình biên dịch sẽ không phàn nàn:
final ThrowingConsumer<String> throwingConsumer = aps -> {
// maybe some other code here...
throw new Exception("asdas");
};
list.forEach(throwingConsumer);
Hoặc thậm chí chỉ cần diễn đạt nó để cô đọng hơn!:
list.forEach((ThrowingConsumer<String>) aps -> {
// maybe some other code here...
throw new Exception("asda");
});
Cập nhật : Có vẻ như có một phần thư viện tiện ích rất hay của Sầu riêng gọi là Lỗi có thể được sử dụng để giải quyết vấn đề này với sự linh hoạt hơn rất nhiều. Ví dụ, trong triển khai của tôi ở trên, tôi đã xác định rõ ràng chính sách xử lý lỗi ( System.out...
hoặc throw RuntimeException
), trong khi Lỗi của Durian cho phép bạn áp dụng chính sách nhanh chóng thông qua một bộ phương pháp tiện ích lớn. Cảm ơn đã chia sẻ nó , @NedTwigg!.
Sử dụng mẫu:
list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));