Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Generic types and collections [duplicate]

I'm trying to learn about the use of generic types and I've noticed something weird when I was experimenting with some lines of code.

The first piece of code is inside a class named "A":

public void func(int k, List list) {
    list.add(9);
    list.add(true);
    list.add("a string");
    }

The second piece of code is in a different class, inside the main function:

List<Integer> arr = new ArrayList<Integer>();
        arr.add(14);
        System.out.println(arr.toString());
        a.func(8, arr);
        System.out.println(arr.toString());

Running the code results in this lines being printed:

[14]

[14, 9, true, a string]

This got me pretty confused since arr is an ArrayList of type Integer, how can it contain objects of type boolean and String? Is there a transformation of the list in the function func to a raw type (which mean it becomes of generic type Object)? And if so how is it possible since you cannot do this for example: List<Integer> arr = new ArrayList<Object>();?

Would love some clarification on this, maybe it will help me grasp this subject of generic types better. Thanks!

like image 740
Mickey Avatar asked Oct 18 '22 09:10

Mickey


1 Answers

Java does not allow the creation of generic Arrays. The Java Collection Classes are mainly implemented using Object arrays. The ArrayList class may look like the following

public class ArrayList<T> implements List<T>, Serializable {
    private transient Object[] data;
    // more content...
}

When creating a new Instance of the ArrayList a new Object[] array is created that can hold objects of any type. Typesafety is only achieved through using the generic Type Parameter.

Since List did not provide any Type parameter it makes use of the rawtype and anything can be added to the list. Therefore always make sure to infer template arguments to keep the typesafety.

public void func(int k, List<Integer> list) {
    list.add(9);      // works
    list.add(true);   // compile error
    list.add("a string");  // compile error
}

You should never use rawtypes. Depending on your compiler settings warnings will be omitted. It's better to use (bound/unbound) wildcards.

like image 68
surrz Avatar answered Oct 21 '22 08:10

surrz