Instantiating generic type ArrayList<T>

seeker27 :

I am new to generics and read in a article "A parameterized type, such as ArrayList<T>, is not instantiable — we cannot create instances of them".

Full quote, from Java in a Nutshell:

A parameterized type, such as ArrayList<T>, is not instantiable - we cannot create instances of them. This is because <T> is just a type parameter - merely a place-holder for a genuine type. It is only when we provide a concrete value for the type parameter, (e.g., ArrayList<String>), that the type becomes fully formed and we can create objects of that type.

This poses a problem if the type that we want to work with is unknown at compile time. Fortunately, the Java type system is able to accommodate this concept. It does so by having an explicit concept of the unknown type which is represented as <?>.

I understand that it should not be instantiable since the concrete (actual) type is not known. If so, why does the below code compiles without an error?

public class SampleTest {

    public static <T> List<T> getList(T... elements) {

        List<T> lst = new ArrayList<>(); // shouldn't this line return an error? 

        return lst;
    }
}

I know there is a gap in my understanding of generics here. Can someone point out what am i missing here?

Simeon Ikudabo :

The code that you mention can compile because the Object "lst" is not actually initialized until the method is called. Since the method knows that it will be getting a var-args argument of type T, it can compile in this scenario. Take the example Wrapper class below for example:

public class Wrapper<T> {


    public static <T> List<T> getList(T... elements){
        List<T> lst = new ArrayList<>();
        for(T element: elements) {
            lst.add(element);
        }
        return lst;
}

}

This code can compile because the method hasn't been called. When the method is called, Type T will be the type that we pass as the var-args argument and the code will have no issue compiling. Lets test this in our main method:

 public static void main( String[] args ){

      System.out.println(Wrapper.getList("Hi", "Hello", "Yo"));

 }

And the output is:

[Hi, Hello, Yo]

However, lets generate a compile-time error to see what the article is talking about within our main method:

Wrapper<T> myWrap = new Wrapper<>();

We are actually trying initialize a generic Object of the Wrapper class in the code above, but is unknown. Since the value for the placeholder will be unknown even when we call the method, it results in a compile-time error, whereas creating a List of type T within the getList method does not cause a compile-time error because it will be initialized with a type when the method is called.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=80987&siteId=1