创建通用异常包装器的最佳方法是什么?

What is the best way to create a general Exception wrapper?

是否可以有一个像这样的通用异常包装器?

 public Function<?, Optional<?>> ExceptionWrapper = (? input) -> {
        try {
            return Optional.of(someAction(input));
        } catch (Exception e) {
            logger.warn(e.getMessage());
        }
        return Optional.empty();
    }; 

这些?可以有不同的类型,类似于TS中的Any 目的是不重复相同的代码。

这可能只是一种不好的做法。

你可以使用这样的方法:

public static <T> Optional<T> wrappException(SupplierWithException<T> supplierThatThrowsException) {
    try {
        return Optional.of(supplierThatThrowsException.get());
    }
    catch (Exception e) {
        //logger.warn(e.getMessage()); //TODO add a real logger here
        System.err.println("logger warning: " + e.getMessage());
    }
    return Optional.empty();
};

这个方法获取一个SupplierWithException<T>作为参数,然后执行。因此,您需要像这样创建功能接口 SupplierWithException<T>

@FunctionalInterface
public interface SupplierWithException<T> {
    
    public T get() throws Exception;
}

现在可以像这样使用该方法(假设该方法在 class ExceptionWrapperUtil 中定义):

public static void main(String[] args) {
    Optional<Integer> result1 = ExceptionWrapperUtil.wrappException(//
            //create a SupplierWithException object (as lambda expression, because it's a functional interface)
            //when the get() method is called (within the wrappException method) the calculation is started
            () -> {
                return doCalculations(true);//will throw an exception that is logged
            });
    
    Optional<Integer> result2 = ExceptionWrapperUtil.wrappException(() -> {
        return doCalculations(false);//will succeed without an exception
    });
    
    System.out.println("result1 present: " + result1.isPresent());
    System.out.println("result2 present: " + result2.isPresent());
    System.out.println("result2: " + result2.get());
}

public static int doCalculations(boolean throwException) {
    boolean failed = throwException;//test throwing an exception
    
    //TODO do some calculations...
    int theAnswer = 42;
    
    if (failed) {
        throw new IllegalStateException("calculations failed");
    }
    
    return theAnswer;
}

测试生成以下输出:

logger warning: calculations failed
result1 present: false
result2 present: true
result2: 42


完整示例代码

import java.util.Optional;

public class ExceptionWrapperUtil {
    
    public static <T> Optional<T> wrappException(SupplierWithException<T> supplierThatThrowsException) {
        try {
            return Optional.of(supplierThatThrowsException.get());
        }
        catch (Exception e) {
            //logger.warn(e.getMessage()); //TODO add a real logger here
            System.err.println("logger warning: " + e.getMessage());
        }
        return Optional.empty();
    };
    
    @FunctionalInterface
    public interface SupplierWithException<T> {
        
        public T get() throws Exception;
    }
    
    public static void main(String[] args) {
        Optional<Integer> result1 = ExceptionWrapperUtil.wrappException(//
                //create a SupplierWithException object (as lambda expression, because it's a functional interface)
                //when the get() method is called (within the wrappException method) the calculation is started
                () -> {
                    return doCalculations(true);//will throw an exception that is logged
                });
        
        Optional<Integer> result2 = ExceptionWrapperUtil.wrappException(() -> {
            return doCalculations(false);//will succeed without an exception
        });
        
        System.out.println("result1 present: " + result1.isPresent());
        System.out.println("result2 present: " + result2.isPresent());
        System.out.println("result2: " + result2.get());
    }
    
    public static int doCalculations(boolean throwException) {
        boolean failed = throwException;//test throwing an exception
        
        //TODO do some calculations...
        int theAnswer = 42;
        
        if (failed) {
            throw new IllegalStateException("calculations failed");
        }
        
        return theAnswer;
    }
}

您可以对@Tobias 提供的答案进行一些改进。

在问题中,我可以看到你想要传递一些通用类型的输入(假设 T)并期望和 Optional<R> 类型。

这是新的功能界面,

@FunctionalInterface
public interface FunctionException<T, R> {
        public R apply(T t) throws Exception;
}

然后是新的期望包装器,

public <T,R> Optional<R> wrapException(Function<T, R> function, T t) {
        try { return Optional.of(function.apply(t)); } 
        catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
            //  todo: add logger
        }
        return Optional.empty();
};

您可以将具有以下签名的任何方法传递给 wrapException 方法。

R yourMethod(T t) throws Exception

这是一个例子,

public boolean someMethod(int in) throws IOException {
        // your business logic

        // my business logic
        if (in == 4) throw new IOException("Some exception"); 
        return in == 3;
};

你可以这样调用wrapException

Optional<Boolean> a = wrapException(YourClass::someMethod, 2);
Optional<Boolean> b = wrapException(YourClass::someMethod, 4);