zhouxin
zhouxin

Reputation: 230

Java8: compiler error with generic version in lambda function

Here I just create two simple class Dad and Son, Son is a subclass of Dad.

public class Dad {
 }

public class Son extends Dad {
}

Then I create a Function in other class to test

public class Test {
    public static void main(String[] args) {
        Function<? extends Dad, String> fun = son -> son.toString();
        fun.apply(new Son());
}

But I came across a compiler error on fun.apply(new Son()), it says 'apply (captrue in Funtion cannot be appiled to (Son))'. I am confused, the fun need a param of class which extends Dad, I give the subclass but is not right at all.

What's more! I try new Dad() as the param for the fun, but also got the error message 'apply (captrue in Funtion cannot be appiled to (Dad))'

Finally, I don't know which param can be used when the Function with generic version.

Help~~~ Thanks! (⊙o⊙)

Upvotes: 2

Views: 81

Answers (1)

Misha
Misha

Reputation: 28133

Consider the following:

class Daughter extends Dad {}

Function<Daughter, String> funcForDaughter = ...;
Function<? extends Dad, String> fun = funcForDaughter;  // ok

fun.apply(new Son()); 

If compiler let you do this, you could be passing a Son to a method that only accepts Daughter. The same reason also prohibits you from calling fun.apply(new Dad()).

Function<? extends Dad, String> fun doesn't mean that fun works on any subtype of Dad. It means that fun works on some specific subtype of Dad that's not known at this point.

By declaring fun this way, you make it unsafe to call fun.apply on anything but null and so the compiler won't let you do it.

Upvotes: 2

Related Questions