在 forEach 中使用时 OrElseThrow 出错

Error in OrElseThrow when using within forEach

我需要在 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);
        }

    }

如果我使用普通的 for 循环,它会按预期工作。为什么这对每个循环的 java-8 不起作用?

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

我打赌当前异常class结构是:

class LuciVisionApplicationServiceException extends Exception {}
class ChannelDoesNotExistException extends LuciVisionApplicationServiceException {}

有两种解决方案,它们的结果都是RuntimeException:

  1. ChannelDoesNotExistException 必须扩展 LuciVisionApplicationServiceException,后者必须是 RuntimeException
  2. 的子类型
  3. ChannelDoesNotExistException 必须是 RuntimeException 本身的子类型。

背后的原因很简单。由于传统的 for 循环是方法内部过程代码的一部分,因此在方法级别立即抛出异常。如果将 forEach 与 lambda 表达式一起使用,它会被翻译为匿名的 class Consumer,这不会在方法级别引发异常(Consumer::accept),因此除非使用 RuntimeException 的实例,否则您的构造是不可能的:

subscriptionPack.getChannels().forEach(
    new Consumer<Channel>() {
        @Override
        public void accept(final Channel i) {    // no throwing exception singature

        }
    }
);

JLS §11.2.3 的进一步解释(强调我的):

It is a compile-time error if a lambda body can throw some exception class E when E is a checked exception class and E is not a subclass of some class declared in the throws clause of the function type targeted by the lambda expression.