Christian Christian - 4 days ago 4
Java Question

Shouldn't the type T in addToCollection(T[] a, Collection<T> c) be the same?

I don't understand why the following code works:

import java.util.ArrayList;
import java.util.Collection;

public class Main {

public static void main(String[] args) {
Integer[] arr=new Integer[]{1,2,3};
ArrayList<Object> al=new ArrayList<>();
addToCollection(arr, al);
}
static <T> void addToCollection(T[] a, Collection<T> c)
{
for(T o:a)
c.add(o);
}
}


Shouldn't it be:

...

static <T> void addToCollection(T[] a, Collection<? super T> c)


...?

Shouldn't the type T be the same during the call?

As said in the comments, my question is "which type is inferred for T". Since the code is working, I assume the "higher" type in the hierarchy is inferred.

Answer

Both arr and al are subtypes of Object, so that's what you're getting. If you change your addToCollection function to have a return type, this happens:

public static class Main {

    public static void main(String[] args) {
        Integer[] arr=new Integer[]{1,2,3};
        ArrayList<Object> al=new ArrayList<>();
        Collection<Object> objects = addToCollection(arr, al);  // Compiles
        Collection<Integer> numbers = addToCollection(arr, al); // Doesn't compile
    }

    static <T> Collection<T> addToCollection(T[] a, Collection<T> c)
    {
        for(T o:a) // Behold the side effect
            c.add(o);

        return c;
    }
}
Comments