Reputation: 7543
In java I have the following lambda:
Function<? extends Number, Boolean> f = i -> true;
Next I want to use this lambda the following way:
public <T extends Number> Boolean use(T n) {
return f.apply(n);
}
But the compiler gives 'incompatible types: T cannot be converted to capture#1 of ? extends java.lang.Number'
So what is the reason and how can I use my defined function?
Upvotes: 4
Views: 540
Reputation: 120848
You want that to "consume" elements via the Function
the definition should be:
static Function<? super Number, Boolean> f = i -> true;
The thing is that those definitions are unrelated, you may provide a Function
of some type that extends Number, while your use
method might use some other type that extends Number.
Either create a single class wrapping those two together (like Eran has shown); or declare your Function
that will take Number
; or anything that can be at least a Number
via ? super Number
Upvotes: 2
Reputation: 393801
The issue with applying Function<? extends Number, Boolean> f = i -> true;
in your <T extends Number> Boolean use(T n)
method is that you may assign to f
a function that takes arguments of one sub-class of Number
(say Double
) while your use
method will attempt to pass to it an instance of another sub-class of Number
(say Integer
).
You can change your Function
definition to
Function<Number, Boolean> f = i -> true;
which will accept any type the extends Number
as argument.
Or you can define both the Function
and the method in a single generic class, which would make sure the arguments passed to use()
must match the argument expected by f
:
class Generic<T extends Number> {
Function<T, Boolean> f = i -> true;
public Boolean use(T n) {
return f.apply(n);
}
}
Upvotes: 3