Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bad return type in lambda expression

The following code compiles fine in IntelliJ and Eclipse, but the JDK compiler 1.8.0_25 complains. First, the code.

import java.util.function.Predicate;

public abstract class MyStream<E> {

  static <T> MyStream<T> create() {
    return null;
  }

  abstract MyStream<E> filter(MyPredicate<? super E> predicate);

  public interface MyPredicate<T> extends Predicate<T> {

    @Override
    boolean test(T t);
  }

  public void demo() {
    MyStream.<Boolean> create().filter(b -> b);
    MyStream.<String> create().filter(s -> s != null);
  }
}

The output from javac 1.8.0_25 is:

MyStream.java:18: error: incompatible types: incompatible parameter types in lambda expression
    MyStream.<Boolean> create().filter(b -> b);
                                       ^
MyStream.java:18: error: incompatible types: bad return type in lambda expression
    MyStream.<Boolean> create().filter(b -> b);
                                            ^
    ? super Boolean cannot be converted to boolean
MyStream.java:19: error: bad operand types for binary operator '!='
    MyStream.<String> create().filter(s -> s != null);
                                             ^
  first type:  ? super String
  second type: <null>
MyStream.java:19: error: incompatible types: incompatible parameter types in lambda expression
    MyStream.<String> create().filter(s -> s != null);
                                      ^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
4 errors

When I replace ? super E with simply E, JDK compiles successfully.

When I replace filter(MyPredicate with filter(Predicate, JDK compiles successfully.

Since it works with JDK 1.8.0_60, I suspect it is a compiler bug.

Any details on what caused this and when it has been fixed?

like image 429
Roland Illig Avatar asked Oct 12 '15 15:10

Roland Illig


People also ask

Can lambda expression have return type?

A return statement is not an expression in a lambda expression. We must enclose statements in braces ({}). However, we do not have to enclose a void method invocation in braces. The return type of a method in which lambda expression used in a return statement must be a functional interface.

Is lambda expression good or bad?

It depends. Whenever you find yourself using the same lambda in different places you should consider implementing a class that implements the interface. But if you would've used an anonymous inner class otherwise I think a lambda is far better.

What is the return type of lambda expression must be compatible with which one?

The lambda expression must return a result that is compatible with the result of the functional interface method. If the result is void , the lambda body is void-compatible. If a value is returned, the lambda body is value-compatible.

Can lambda expression return a value?

A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.


1 Answers

If a lambda expression appears in a target type with wildcards (as in most cases)

  Consumer<? super Boolean> consumer = b->{...}

the question arises - what's the type of the lambda expression; in particular, the type of b.

Of course, there could be many choices due to the wildcards; e.g. we could explicitly choose

  Consumer<? super Boolean> consumer = (Object b)->{...}

However, implicitly, b should be inferred as Boolean. This makes sense since the consumer should only be fed with Boolean anyway.

http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.3

If T is a wildcard-parameterized functional interface type and the lambda expression is implicitly typed, then the ground target type is the non-wildcard parameterization of T

(This probably assumes that wildcards are use properly variance-wise on the target type; we might find some hilarious examples if the assumption doesn't hold)

like image 69
ZhongYu Avatar answered Oct 04 '22 16:10

ZhongYu