Java add list of specific class to list of java.lang.Object works with java 8 streams - why?

user817795 :
public class Test {

    static List<Object> listA = new ArrayList<>();

    public static void main(final String[] args) {
        final List<TestClass> listB = new ArrayList<>();
        listB.add(new TestClass());

        // not working
        setListA(listB);

        // working
        setListA(listB.stream().collect(Collectors.toList()));

        System.out.println();
    }

    private static void setListA(final List<Object> list) {
        listA = list;
    }

}

why does it work with streams and does not work for the simple set?

Oliver Charlesworth :

For the first case, it fails because List<TestClass> is not a subtype of List<Object>.1

For the second case, we have the following method declarations:

interface Stream<T> {
    // ...
    <R, A> R collect(Collector<? super T, A, R> collector)
}

and:

class Collectors {
    // ...
    public static <T> Collector<T, ?, List<T>> toList()
}

This allows Java to infer the generic type parameters from the context.2 In this case List<Object> is inferred for R, and Object for T.

Thus your code is equivalent to this:

Collector<Object, ?, List<Object>> tmpCollector = Collectors.toList();
List<Object> tmpList = listB.stream().collect(tmpCollector);
setListA(tmpList);

1. See e.g. here.

2. See e.g. here or here.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=444108&siteId=1