Java 8 为什么可以';我们不能在Java8流中抛出异常吗?

Java 8 为什么可以';我们不能在Java8流中抛出异常吗?,java-8,java-stream,Java 8,Java Stream,例如: 我在寻找不被允许的原因?即使声明代码的方法抛出IOException,您的代码也能正常工作,除了throw new…行末尾缺少分号,以及//code here中可能隐藏的缺少返回语句之外 您不能做的是抛出一个选中的异常(RuntimeException不是),因为选中的异常是方法签名的一部分,而Predicate.test方法不声明一个 编辑: 为了更准确地了解发生了什么以及为什么不能在此处抛出选中的异常,下面是如何在没有lambda的情况下编写代码: 由此: Person result

例如:


我在寻找不被允许的原因?即使声明代码的方法抛出IOException,您的代码也能正常工作,除了
throw new…
行末尾缺少分号,以及
//code here
中可能隐藏的缺少返回语句之外

您不能做的是抛出一个选中的异常(RuntimeException不是),因为选中的异常是方法签名的一部分,而Predicate.test方法不声明一个

编辑: 为了更准确地了解发生了什么以及为什么不能在此处抛出选中的异常,下面是如何在没有lambda的情况下编写代码:

由此:

Person result = persons.stream()
                  .filter(x -> {
                    if ("test".equals(x.getName() ) ) {
                      throw new IOException("not possible inside stream y ?"); //any checked exception
                    }
                    //code here
                  })
为此:

public Person myMethod() throws IOException {
    Person result = persons.stream()
              .filter(x -> {
                if ("test".equals(x.getName() ) ) {
                  throw new IOException("not possible inside stream y ?"); //any checked exception
                }
                //code here
                return true;
              });
    return person;
}
public Person myMethod()引发IOException{
Person结果=persons.stream()
.filter(新谓词(){
公共布尔测试(人x){
如果(“test”.equals(x.getName())){
抛出新IOException(“在流y中不可能?”);//任何选中的异常
}
//代码在这里
返回true;
}
});
返回人;
}
如您所见,lambda表达式中的代码现在位于匿名
谓词
类的
test
方法中,该类未声明任何已检查异常

为什么
谓词
?因为它是
过滤器
方法所期望的,并且您可以使用lambda而不是常规对象,因为它是一个单一的方法接口:只有
test
是抽象的,并且您的lambda签名应该与
谓词.test
方法相同

如果您真的希望能够处理选中的异常,那么(在Frederico的评论中)将展示一些绕过这些限制的方法

寻找不被允许的原因

您正在实现一个
谓词
,该谓词不声明选中的异常

例外情况是副作用,功能设计人员不喜欢,这很可能是它们没有得到很好支持的原因

我使用了一个技巧来传递签出的异常并稍后捕获它。另一个选项是使用未检查的异常对其进行包装,或者在不同的情况下使用类似于
IORuntimeException
的类,我使用这三个选项


您得到的错误是什么?也许是一份丢失的返回声明?我认为这应该是可能的。lambda必须返回一个
布尔值。除此之外你很好。抱歉更新了我的问题。即使在方法签名中声明为throws,或者整个表达式处于try/catch下,我也无法抛出选中的异常。。。。寻找原因为什么?或者如果我们有其他方法可以做到这一点。可能重复感谢@Federico。所以这是我的问题。即使在方法签名中声明为throws,或者整个表达式处于try/catch下,我也无法抛出选中的异常。。。。寻找原因为什么?或者如果我们有办法做到这一点,我不会说lambda表达式在
test
方法中,这太误导人了。lambda表达式在
myMethod
中,但它必须满足
test
方法的签名约束。@Holger:我不是指lambda表达式,而是指lambda中的代码。我将编辑以澄清这一点。我知道你的意思,但lambda表达式的代码不在
test
方法中;
test
方法中的代码可以访问
谓词
接口的继承成员,在
test
方法中,
引用
谓词
实例。两者都不适用于lambda表达式的代码,它无法访问
谓词
成员,并且
引用了
myMethod()
的所有者。此外,可访问性规则也不同。与
test
方法的唯一关系是履行其签名合同的要求。关于可访问性规则的优点。我将进一步编辑以删除错误的部分
public Person myMethod() throws IOException {
    Person result = persons.stream()
              .filter(new Predicate<Person>() {
                  public boolean test(Person x) {
                      if ("test".equals(x.getName() ) ) {
                          throw new IOException("not possible inside stream y ?"); //any checked exception
                      }
                      //code here
                      return true;
                  }
              });
    return person;
}