2016-04-14 15 views
6

Tôi đang sử dụng API Java 8 Stream và vì chúng tôi biết nó không hỗ trợ các ngoại lệ đã kiểm tra bên trong bất kỳ giao diện chức năng nào bên trong java.util.function.Có phải là giải pháp tốt để sử dụng chức năng trang trí được kiểm tra trong API luồng không?

tôi thường phải sử dụng phương pháp với ngoại lệ kiểm tra bên trong hoạt động suối và tôi đã viết CheckedFunction trang trí để sử dụng trong những hoạt động:

import java.util.function.BiFunction; 
import java.util.function.Function; 

public interface CheckedFunction<T, R, E extends Throwable> { 

    R apply(T t) throws E; 

    static <T, R, CE extends Throwable, UCE extends RuntimeException> Function<T, R> checked(
      CheckedFunction<T, R, CE> checked, Function<CE, UCE> exceptionHandler) { 
     return (t) -> { 
      try { 
       return checked.apply(t); 
      } 
      catch (RuntimeException | Error e) { 
       throw e; 
      } 
      catch (Throwable e) { 
       // can't catch - compiler error 
       if (e instanceof InterruptedException) { 
        Thread.currentThread().interrupt(); 
       } 
       throw exceptionHandler.apply((CE) e); 
      } 
     }; 
    } 
} 

vì vậy tôi có thể sử dụng nó trong những trường hợp như:

entities.stream() 
     .map(checked((entity) -> someResultChecked(entity), // throws IOException 
        (entity, e) -> { // e is of type IOException 
         log.error("exception during checked method of " + entity, e); 
         return new UncheckedIOException(e); 
        })) 
     .map(checked((entity) -> saveToDb(entity), // throws SQLException 
        (entity, e) -> { // e is of type SQLException 
         log.error("exception during saving " + entity, e); 
         return new UncheckedSQLException(e); 
        })) 
     .map(checked((entity) -> manyExceptionMethod(entity), // throws IOException, SQLException 
        (entity, e) -> { // e is of type Throwable 
         return new RuntimeException(e); 
        })) 

Nó sẽ bọc bất kỳ ngoại lệ kiểm tra để bỏ chọn, nhưng tôi biết nếu phương pháp được ném nhiều hơn một ngoại lệ nó sẽ xóa để Throwable, tôi sẽ sử dụng nó trong trường hợp đơn giản.

Ý tưởng hay là tôi có thể gặp phải những trở ngại tiềm ẩn?

CẬP NHẬT: Làm lại RuntimeExceptions.

Ngoài ra tôi tìm thấy giải pháp rõ ràng hơn trong jOOL với xử lý InterruptedException mà có thể gây ra hành vi không phù hợp sẽ bị bỏ qua nếu: https://github.com/jOOQ/jOOL/blob/master/src/main/java/org/jooq/lambda/Unchecked.java

+1

Bạn nên có một cái nhìn tại JavaRx mà cung cấp một API tốt đẹp cho streaming với xử lý lỗi – flakes

+0

Cảm ơn, tôi đã cố gắng để nhìn vào nhiều lần, nhưng luôn luôn cho up.Maybe đó là một tín hiệu mà tôi cần để sắp xếp nó ra . – Monk3D

Trả lời

0

Bạn sẽ nhận được một ClassCastException nếu bất cứ điều gì khác hơn là một IOException bị ném, vì bạn bắt tất cả Throwable và chuyển chúng vào hàm tạo UncheckedIOException, chỉ mất một tham số IOException. Kể từ khi bắt IOException trong một loại chức năng là một nhu cầu phổ biến, thay vì cố gắng khái quát hóa, có thể tốt nhất là giữ cho nó đơn giản và tạo một cái chỉ cho ngoại lệ đã kiểm tra đó. Tôi sẽ tưởng tượng bạn hiếm khi cần phải lặp lại mã để làm tương tự cho các trường hợp ngoại lệ được kiểm tra khác.

@FunctionalInterface 
public interface CheckedIOFunction<T,R> { 

    R apply(T t) throws IOException; 

    static <T, R> Function<T, R> toUnchecked(CheckedIOFunction<T, R> function) { 
     return t -> { 
      try { 
       return function.apply(t); 
      } catch (IOException ioe) { 
       throw new UncheckedIOException(ioe); 
      } 
     }; 
    } 
} 
+1

Không thực sự, infers từ phương pháp tôi sử dụng. Vì vậy, nếu tôi sẽ sử dụng phương thức ném IOException nó sẽ là và trong exceptionHandler bạn sẽ nhận được kiểu IOException, và nếu nó ném bất cứ điều gì khác sẽ là loại của nó (hoặc loại Throwable nếu có sẽ được nhiều ngoại lệ). Ví dụ: bạn có thể chạy ví dụ và xem đầu ra https://gist.github.com/gavlyukovskiy/30e28bae4b572b5a67c3a7c432069f46 – Monk3D

+0

Đó là một ý tưởng thú vị. Có bất kỳ loại ngoại lệ cuối cùng nào thường bị ném không? –

+0

Thông thường, chúng tôi chỉ sử dụng một ngoại lệ duy nhất, vì vậy nó có thể được xử lý bằng analog tương tự. Hoặc chúng tôi thường xuyên ném UserApiException để cho biết vấn đề yêu cầu của người dùng. – Monk3D

Các vấn đề liên quan