使用orElseThrow时出现循环接口错误

dan*_*ker 8 java lambda guava java-8

使用Guava's ClassPath我正在尝试初始化位于特定包中的类,但我想使用构造函数进行初始化,因为它不会传播异常.所以这就是我为获得构造函数而设计的:

ClassPath.from(classLoader).getTopLevelClasses("test.package").stream()
    .map(ClassPath.ClassInfo::load)
    .map(Class::getConstructors)
    .map(Arrays::stream)
    .map(constructorStream -> constructorStream
        .filter(constructor -> constructor.getParameterCount() == 0)
        .findAny()
        .orElseThrow(RuntimeException::new)
    );
Run Code Online (Sandbox Code Playgroud)

但是,这只是在简单地说明Cyclic接口时在InteliJ中给出错误.我想我知道Cyclic接口是什么,但我不确定为什么会导致这个错误.据我所知,只要返回类型是已知的(orElseThrow在这种情况下它具有返回值Constructor<?>),那么抛出未经检查的异常应该没问题.如果我使用orElse(null)那么错误消失了.这里发生了什么以及如何抛出我想抛出的RuntimeException?

sta*_*let 0

运行时异常是从映射 lambda 内部抛出的。实际的异常可以在 Stream api 内部处理。

为了避免这种情况,您可以使用 flatMap 方法将当前流替换为提供给 flatMap 方法的组合流。这通常在组合流时使用。另请参阅adam bien 在平面图上的示例。

在此示例中,异常不必通过流 api - 因此您还可以使用已检查的异常,而不受 Stream 接口中没有 throws 子句的签名的限制。

    ClassPath.from(classloader).getTopLevelClasses("test.package").stream()
            .map(ClassPath.ClassInfo::load)
            .map(Class::getConstructors)
            .flatMap(Arrays::stream)
            .filter(constructor -> constructor.getParameterCount() == 0)
                    .findAny()
                    .orElseThrow(RuntimeException::new);
Run Code Online (Sandbox Code Playgroud)