3

I have the following class, which represents an entity that can be identified by a String id:

public abstract class IdentifiableEntity {

    private String id;

    // getters & setters
}

Then, I have the following interface, which represents an object that can be filled with data coming from the argument:

public interface Fillable<T> {

    void fill(T full);
}

Fillable objects are always filled with full copies of the same class, i.e. a Fillable Person would be used this way:

public class Person implements Fillable<Person> {

    // attributes, getters & setters

    public void fill(Person full) {
        // deeply copy data from full person to this person
    }
}

Finally, I have the following interface, whose default method receives a stream of objects that are both IdentifiableEntity and Fillable, and an empty object that is also IdentifiableEntity and Fillable:

public interface Hydrator {

    default <T extends IdentifiableEntity & Fillable<T>> void searchAndFill(
        Stream<T> stream, T empty) {

        stream
            .filter(p -> p.getId().equals(empty.getId()))
            .findAny()
            .ifPresent(e -> empty.fill(e));
    }
}

The above code both compiles and works fine. It searches an element from the stream by id and uses it to fill the empty object.

However, when I change the final lambda expression to its equivalent method reference:

stream
    .filter(p -> p.getId().equals(empty.getId()))
    .findAny()
    .ifPresent(empty::fill);

This compiles fine, but fails with the following runtime exception:

java.lang.invoke.LambdaConversionException: Invalid receiver type class IdentifiableEntity; not a subtype of implementation type interface Fillable
    at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233)
    at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
    at java.lang.invoke.CallSite.makeSite(CallSite.java:302)    
... 55 common frames omitted

JDK version is "1.8.0_65".

fps
  • 33,623
  • 8
  • 55
  • 110
  • 3
    Related, possibly a duplicate: [LambdaConversionException with generics: JVM bug?](http://stackoverflow.com/questions/27031244/lambdaconversionexception-with-generics-jvm-bug) – rgettman Apr 20 '16 at 20:56
  • 2
    Looks very similar to http://stackoverflow.com/questions/33925551/enum-interfaces-and-java-8-lambdas-code-compiles-but-fails-at-runtime-is-th (intersection types & method references & works with a lambda) – Tunaki Apr 20 '16 at 21:04
  • After .findAny() you should use .map() and convert it into your return type.... – Moinkhan Apr 22 '16 at 05:00

0 Answers0