Nếu bạn muốn xử lý ngoại lệ đã kiểm tra một cách an toàn, bạn cần có phương pháp trợ giúp cung cấp cơ sở bao gồm ngoại lệ thành loại phụ RuntimeException
. Dưới đây là ví dụ một hàm helper trong đó sử dụng an toàn kiểu Generic để đảm bảo rằng chỉ tuyên bố trường hợp ngoại lệ sẽ được tái ném (trừ khi bạn sử dụng một hoạt động không an toàn):
public static <E extends Throwable> void attempt(
Consumer<Function<E,RuntimeException>> action) throws E {
final class CarryException extends RuntimeException {
final E carried;
CarryException(E cause) {
super(cause);
carried=cause;
}
}
try { action.accept(CarryException::new); }
catch(CarryException ex) { throw ex.carried; }
}
Nó hỗ trợ một tùy action
đó sẽ nhận được một chức năng mà không gói tạm thời của loại ngoại lệ đã kiểm tra vào RuntimeException
. Gói này sẽ được minh bạch, phương pháp attempt
sẽ hoàn thành bình thường hoặc ném ngoại lệ đã kiểm tra ban đầu E
(hoặc một ngoại lệ không được kiểm soát không liên quan nếu xảy ra).
Vì vậy, bạn có thể sử dụng nó như thế này:
public static void processIterm(Supplier<Key> s)
throws SomeCheckedException {
attempt((Function<SomeCheckedException, RuntimeException> thrower) ->
Optional.ofNullable(s).ifPresent(nonNull -> {
try { key(nonNull.get()); } // assuming key may throw SomeCheckedException
catch(SomeCheckedException e) { throw thrower.apply(e); }
}));
}
Do các hoạt động lồng trình biên dịch không thể suy ra các ngoại lệ gõ tự động. Đoạn mã trên sử dụng khai báo rõ ràng loại thông số thrower
. Hoặc bạn có thể sử dụng lời gọi kiểu của phương thức trợ giúp như
ContainingClass.<SomeCheckedException>attempt(thrower ->
Optional.ofNullable(s).ifPresent(nonNull -> {
try { key(nonNull.get()); }
catch(SomeCheckedException e) { throw thrower.apply(e); }
}));
Ah, tôi không nghĩ rằng 'khóa (…)' có thể ném ngoại lệ đã kiểm tra. Tuy nhiên [câu trả lời của tôi] (http://stackoverflow.com/a/27900544/2711488) cũng xử lý trường hợp đó. – Holger