使用lambda表达式时,Java 8泛型+异常编译时错误 [英] Java 8 generics + exceptions compile time error when using a lambda expression

查看:501
本文介绍了使用lambda表达式时,Java 8泛型+异常编译时错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天前,我开始重构一些代码以使用新的Java 8 Streams库。不幸的是,在执行Stream :: map时,遇到了一个编译时错误,该方法被声明为抛出一个泛型E,该泛型E被进一步指定为RuntimeException。



有趣的是,当我切换到使用方法引用时,编译时错误消失。



这是一个错误还是我的方法引用不等于我的lambda表达式?



(另外,我知道我可以使用Parameter :: execute替换p-> p.execute(foo)。我的实际代码具有execute方法的其他参数)。






错误讯息

 错误:(32,43)java:未报告的异常E;必须被捕获或被宣告为被抛出






代码

  import java.util.ArrayList; 
import java.util.List;


public class JavaBugTest
{
interface AbleToThrowException< E extends Exception>
{
}

接口参数{
public< E extends Exception>对象执行(AbleToThrowException< E>算法)抛出E;
}

接口ThrowsRuntimeException继承了AbleToThrowException< RuntimeException>
{
}

static ThrowsRuntimeException foo;


public static Object manualLambda(Parameter p)
{
return p.execute(foo);


public static void main(String [] args)
{
List< Parameter> params = new ArrayList<>();
params.stream()。map(p - > p.execute(foo)); //提供编译时错误。
params.stream()。map(JavaBugTest :: manualLambda); // 工作正常。
}

}






系统设置


  • 操作系统:Windows x64
  • Java编译器版本:Oracle JDK 1.8.0_11
  • IDE:Intellij

解决方案

一个非常简单的解决方案是为参数#execute(..)显式提供一个类型参数。

  params.stream()。map(p  - > p。< RuntimeException> execute(foo)); //提供编译时错误。 

没有显式类型参数,JDK编译器似乎无法从调用上下文中推断出类型参数,尽管它应该。这是一个错误,应该这样报告。我现在已经报道了它,并且会在我有它们时用新的详细信息更新这个问题。



错误报告


A couple of days ago, I started refactoring some code to use the new Java 8 Streams library. Unfortunately, I ran into a compile time error when performing Stream::map with a method which is declared to throw a generic E that is further specified to be a RuntimeException.

Interesting enough, the compile time error goes away when I switch to using a method reference.

Is this a bug, or is my method reference not equivalent to my lambda expression?

(Also, I know I can replace p->p.execute(foo) with Parameter::execute. My actual code has additional parameters for the execute method).


Error message

Error:(32, 43) java: unreported exception E; must be caught or declared to be thrown


Code

import java.util.ArrayList;
import java.util.List;


public class JavaBugTest
{
    interface AbleToThrowException<E extends Exception>
    {
    }

    interface Parameter {
        public <E extends Exception> Object execute(AbleToThrowException<E> algo) throws E;
    }

    interface ThrowsRuntimeException extends AbleToThrowException<RuntimeException>
    {
    }

    static ThrowsRuntimeException foo;


    public static Object manualLambda(Parameter p)
    {
        return p.execute(foo);
    }

    public static void main(String[] args)
    {
        List<Parameter> params = new ArrayList<>();
        params.stream().map(p -> p.execute(foo)); // Gives a compile time error.
        params.stream().map(JavaBugTest::manualLambda); // Works fine.
    }

}


System setup

  • OS: Windows x64
  • Java compiler version: Oracle JDK 1.8.0_11
  • IDE: Intellij

解决方案

A very simple solution is to explicitly provide a type argument for Parameter#execute(..).

params.stream().map(p -> p.<RuntimeException>execute(foo)); // Gives a compile time error.

Without the explicit type argument, it seems like the JDK compiler cannot infer a type argument from the invocation context, though it should. This a bug and should be reported as such. I have now reported it and will update this question with new details when I have them.

Bug Report

这篇关于使用lambda表达式时,Java 8泛型+异常编译时错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆