Search code examples
javagenericsgeneric-listgeneric-collections

What is the difference between <> and <?> in Java generic types?


When you create a collection field that takes a generic type you can do that by giving it ? as the value or nothing at all what is the difference between those:

e.g.

List<String> list = new ArrayList<?>();

List<String> list = new ArrayList<>();

List<String> list = new ArrayList<String>();

Solution

  • The first statement is just wrong; you cannot instantiate a parameterized class with an unknown type. You are likely confusing it with a similar syntax where the unknown is on a declared type as in this dummy example:

    public static String getClassName(Class<?> clazz) {
       return clazz.getName();
    }
    

    In the example above, the use of <?> indicates that any type instantiation may be provided.

    The last two statements are equivalent; in new ArrayList<>(), the String type parameter is inferred by the compiler from the declared type on the left-hand side, while in the last statement this is given explicitly. As others have correctly noted, this type inference is only available as of Java 7. Prior to Java 7, you can achieve similar type inference by taking advantage of the way that types are inferred on method invocations; for example, Guava's Lists.newArrayList() allows one to write "Lists.newArrayList()" on the right-hand side without specifying the type a second time, and pre-JDK7 compilers will properly infer the type from the left-hand side there.