无法在 lambda 表达式中触发异常

Cannot trigger an exception within an lambda expression

我对 Java 8 有点陌生,我试图在 lambda 表达式中抛出一个异常,如下所示:如果 subQty 小于最小值或大于最大值,在这种情况下,我的单元测试计算min/max 为 182 和 255,我提交的子数量为 10,因此它应该引发异常并未能通过此单元测试。但是,我总是获得绿灯,这是为什么?

public void verifyingIndividualSubmissionValueLimits(String alias, double min, double max)
    // ... some code here ...

    // Get local stock price
    CompletableFuture<Double> localPriceFuture = instrumentRequester.getMidPrice(instId);

    // Calculate the min and max quantity
    localPriceFuture.thenAcceptBoth(dollarFxRateFuture,
            (localPrice, fxRate) -> {
                double minLocalValue = min * fxRate;
                double maxLocalValue = max * fxRate;
                long minQuantity = Math.round(minLocalValue / localPrice);
                long maxQuantity = Math.round(maxLocalValue / localPrice);
                if (subQty < minQuantity || subQty > maxQuantity) {
                    log.debug("We should throw an exception because subQty is {}", subQty);
                    throw new SubmissionValidationException(String.format("Quantity: %s, is not within %s and %s", subQty, minQuantity, maxQuantity));
                }
            }
    );
}

您在不同的线程中抛出异常。您正在创建一个计算最小、最大速率并抛出异常的线程,但异常发生在线程中,因此您在主线程中看不到任何异常(在本例中为 verifyingIndividualSubmissionValueLimits)。您可以在此处阅读回调和异步线程 https://www.callicoder.com/java-8-completablefuture-tutorial/

只有当它代表的@FunctionInterface 抛出异常时,您才能从 lambda 内部抛出异常,否则您将只能在 lambda 内部处理它,例如这个可以实现创建自己的 FunctionalInterface -

public class Test {

    public void foo(Fun f) throws Exception {
        f.apply();
    }

    @FunctionalInterface
    private interface Fun{
        void apply() throws Exception;
    }

    public static void main(String[] args) throws Exception {
        Test test = new Test();
        test.foo(() -> {
           throw new Exception();
        });
    }
}

在您的情况下,您使用的是 CompletableFuture thenAcceptBoth 函数,它使用 BiConsumer 函数接口,不会抛出任何异常,因此不可能从那里抛出它。

@FunctionalInterface
public interface BiConsumer<T, U> {
    void accept(T t, U u);
    ....
}

这些是编译时限制,即使它不在单独的线程中也是有效的。