Java 在forEach中使用时OrElseThrow中出错

Java 在forEach中使用时OrElseThrow中出错,java,spring-boot,lambda,java-8,optional,Java,Spring Boot,Lambda,Java 8,Optional,我需要在forEach循环中使用OrElseThrow 这是我的密码:- Service.java public SubscriptionPack saveSubscriptionPack(SubscriptionPack subscriptionPack) throws LuciVisionApplicationServiceException { if (subscriptionPackRepository.findByName(subscri

我需要在forEach循环中使用OrElseThrow

这是我的密码:-

Service.java

    public SubscriptionPack saveSubscriptionPack(SubscriptionPack subscriptionPack)
            throws LuciVisionApplicationServiceException {
        if (subscriptionPackRepository.findByName(subscriptionPack.getName()).isPresent()) {
            throw new SubscriptionPackAlreadyExistsException("Subscription Pack With THe Given name 
             Already Exists");
        } else {
            List<Channel> channels = new ArrayList<>();
            float price = 0;
            subscriptionPack.getChannels().forEach(i -> {
                // Error Here saying "Unhandled exception type ChannelDoesNotExistException" and 
                // asking to surround with try Catch but OrElseThrow should have handled it
                Channel ch = channelRepository.findByName(i.getName())
                        .orElseThrow(() -> new ChannelDoesNotExistException("Channel With Given Name 
                         Does Not Exist"));
                channels.add(ch);
            });
            return new SubscriptionPack(subscriptionPack.getName(), null, channels);
        }

    }
public SubscriptionPack saveSubscriptionPack(SubscriptionPack SubscriptionPack)
引发LuciVisionApplicationServiceException{
if(subscriptionPackRepository.findByName(subscriptionPack.getName()).isPresent()){
抛出新SubscriptionPackageReadyExistsException(“具有给定名称的订阅包
已经存在);
}否则{
列表通道=新的ArrayList();
浮动价格=0;
subscriptionPack.getChannels().forEach(i->{
//此处显示“未处理的异常类型ChannelDoesNotExistException”和
//要求用试抓围住,但OrElseThrow应该已经处理好了
Channel ch=channelRepository.findByName(i.getName())
.orelsetrow(()->new ChannelDoesNotExistException(“具有给定名称的通道
不存在“);
频道。添加(ch);
});
返回新的SubscriptionPack(SubscriptionPack.getName(),null,通道);
}
}
如果我使用普通for循环,它将按预期工作。为什么java-8不支持每个循环


PS:我的存储库返回可选。

我打赌当前的异常类结构是:

class LuciVisionApplicationServiceException extends Exception {}
class ChannelDoesNotExistException extends LuciVisionApplicationServiceException {}
有两种解决方案,它们都会导致:


  • ChannelDoesNotExistException
    必须扩展
    LuciVisionApplicationServiceException
    ,它必须是
    RuntimeException

  • ChannelDoesNotExistException
    必须是
    RuntimeException
    本身的子类型
  • 背后的原因很简单。由于传统的for循环是方法内部过程代码的一部分,因此异常将作为excepted立即在方法级别抛出。如果将
    forEach
    与lambda表达式一起使用,则会将其转换为匿名类,该类不会在方法级别()上引发异常,因此除非使用的实例是:

    subscriptionPack.getChannels().forEach(
    新消费者(){
    @凌驾
    公共无效接受(最终通道i){//无抛出异常信号
    }
    }
    );
    
    进一步解释(重点):

    E
    是一个选中的异常类,并且E不是lambda表达式所针对的函数类型的throws子句中声明的某个类的子类时,如果lambda主体可以抛出某个异常类
    E
    ,则这是一个编译时错误


    ChannelDoesNotExistException
    似乎是一个已检查的异常,而lambdas(在forEach()中)通常不能抛出已检查的异常。你说的“不起作用”是什么意思?你有错误吗?意外的结果?有道理,谢谢。是的,我在我的应用程序中使用了您演示的异常层次结构。
    subscriptionPack.getChannels().forEach(
        new Consumer<Channel>() {
            @Override
            public void accept(final Channel i) {    // no throwing exception singature
    
            }
        }
    );