George
George

Reputation: 7543

Lambda with wildcard generic type

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

Answers (2)

Eugene
Eugene

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

Eran
Eran

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

Related Questions