无法在 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);
....
}
这些是编译时限制,即使它不在单独的线程中也是有效的。
我对 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);
....
}
这些是编译时限制,即使它不在单独的线程中也是有效的。