Reputation: 43
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
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
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