user3242143
user3242143

Reputation: 43

Compilation error when passing Integer into generic method with Function<T, ? extends Number>>

I have some code with 3 overriding methods that perform the same operation ( code is identically for each method) on the Inputs, the only difference between them is the input parameter type

private List<String> extractDoubleValues(Function<MyClass, List<Double>> extractions)
private List<String> extractLongValues(Function<MyClass List<Long>> extractions)
private List<String> extractIntegerValues(Function<MyClass, List<Integer>> extractions)

I was trying to attempt to replace these 3 methods with a single method that makes us of generic wildcards as follows

private List<String> extractNumberValues(Function<MyClass, List<? extends Number>> extractions)

When I attempt to use the above generic method in place of one of the 3 type specific methods

Function<MyClass, List<Integer>> intExtractions; 
List<String> extractedValues = extractNumberValues(intExtractions);

I get a the following compilation error on the second line of code above

Error:(59, 80) java: incompatible types: java.util.function.Function<MyClass,java.util.List<java.lang.Double>> cannot be converted to java.util.function.Function<MyClass,java.util.List<? extends java.lang.Number>>

I've successfully replaced duplicate methods with the wildcard before, as bellow

List<String> convertNumberListToStringList(List<Integer> numberList)
List<String> convertNumberListToStringList(List<Double> numberList)

with

List<String> convertNumberListToStringList(List<? extends Number> numberList)

I'm new to the idea of generics so I was curious as why the above would fail to compile? I do not quite understand why it would fail to compile

Upvotes: 4

Views: 310

Answers (2)

Majlanky
Majlanky

Reputation: 304

Major problem(or i should say feature?) here is generic are used only during compilation. During runtime you do not have any information about generic. In other words you have to consider List<Integer> and List<Double> and completelly different types. If you see inside Fucntion class you will see <T, R> without wildcard. So even Function use List<Integer> and List<Double> as completelly different types. If y ou want to say to Function that R will be something of List type, you have to code it like:

Function<SomeClass, ? extends List<? extends SomeOtherClass>>

By code above you are telling that R will be List for sure and list will contain instances of SomeOtherClass.

Main point during work with generic is that generic changes original class to some other class...

Upvotes: 1

Pradeep Pati
Pradeep Pati

Reputation: 5919

When you declare the instance of Function<MyClass, List<Number>> as Function<MyClass, List<Integer>> you restrict other types of number to be added to the List, i.e. Long and Double can't be added to the List<Integer>. Hence the incompatible type error.

Upvotes: 1

Related Questions