Java 8 generics + exceptions compile time error wh

2020-06-16 02:45发布

问题:

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

回答1:

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