Can someone help me with understanding logic behind this code:
import java.util.List;
import java.util.Arrays;
interface DoubleValue<T> {
public void dv(T e);
}
public class InTest2 {
public static void main(String[] a) {
DoubleValue<Number> func = e -> System.out.println(e.doubleValue());
List<Number> l = Arrays.asList(1, 2, 3);
InTest2.sumOfListNotWorking(l, func);
InTest2.sumOfListWorking(l, func);
InTest2.sumOfListWorkingSuper(l, func);
}
// I thought this should work
public static void sumOfListNotWorking(List<? extends Number> list, DoubleValue<? extends Number> f) {
for (Number n : list)
f.dv(n); // This line give error: The method dv(capture#2-of ? extends Number) in the type DoubleValue<capture#2-of ? extends Number> is not applicable for the arguments (Number)
}
public static void sumOfListWorking(List<? extends Number> list, DoubleValue<Number> f) {
for (Number n : list)
f.dv(n);
}
public static void sumOfListWorkingSuper(List<? extends Number> list, DoubleValue<? super Number> f) {
for (Number n : list)
f.dv(n);
}
}
sumOfListNotWorking:
Here I pass to DoubleValue.dv(<? extends Number> e)
a Number and I thought it's OK.
But compiler says that it's not. Why?
I expect with DoubleValue<Number>.dv
as e -> e.doubleValue()
this should be typical consumer: I get value <? extends Number>
and do something with it.
sumOfListWorkingSuper:
Behavior of sumOfListWorkingSuper
puzzles me too.
Interface DoubleValue<? super Number>
can't be a consumer cause value of <? super Number>
can't be changed in place (Number is immutable), but compiler is OK with it.
UPDATE:
Apparently I didn't understand correctly logic of "producer" and "consumer".
sumOfListNotWorking:
This method doesn't compile because I use:
List<? extends Number> list
as a producer (in method I take out values from list with loop).DoubleValue<? extends Number>
as a consumer (in method I passNumber
tof.dv(n)
), but when I try to pass valueNumber
tof
compiler told me thatf
is defined as a producer (<? extends Number>
- have some values ofNumber
or it's children) and it can not accept any values. What if I passed tof
argumentDoubleValue<Integer>
then I would try to putNumber
where should beInteger
- this isn't possible. All this error happens because I define a producer instead of a consumer.
Thanks for pointing out word accept in logic of a consumer and a producer.