List<? >List<Object>The difference between

The difference between:

  1. List<? >The elements of a variable can only be read, not written (can be insertednullElements)
  2. List<Object>notList<String>Parent class, butList<? >Is the parent of all List generics, soList<? >Variables can be assigned to a variety of List generic types
public static void printList(List<Object> list) {
    for (Object elem : list)
        System.out.println(elem + "");
    System.out.println();
}
Copy the code

The method defined in the above code can only accept variables of type Listas arguments, not List

. > is acceptable.

List<? >ListThe difference between

List
is the parent of all List generics, and List is the raw type of List generics. List primitives are allowed in order to be compatible with the code before generics were introduced. Using primitives would lose the safety and expressiveness of generics, and might cause errors at runtime and require transformation. So the compiler gives a warning.

Note that there are some scenarios that need to use the original type:

  1. You must use the original type in class literals,List.class,String[].classint.classThat’s right, butList<? >.class List<String>.classIs wrong.
  2. The primitive type is sufficient in the instanceof operator because generic information is erased at run time. Only the unbounded wildcard type or primitive type can be used in the instanceof operator, and there is no difference between the two. The latter is recommended.
// Recommended usage of the instanceof operator
if (o instanceofSet) { Set<? > s = (Set<? >) o;// This transition is checked, with no compile-time warnings
}
Copy the code

<? >Usage scenarios of

In the in-out usage rules for generic wildcards:

  1. The List variable (in) used to read, with extend defining the lower bound; If only methods of the Object class are called, use the unbounded wildcard
  2. The List variable (out) used for writing is bound using super
  3. Wildcards are not used when List variables also require in-out access

For example, the List interface of the JDK source containsAll, removeAll methods are
defined:

boolean containsAll(Collection
        c);
boolean removeAll(Collection
        c);
Copy the code

The addAll method, while also reading, will call E’s method for subsequent use, so it cannot use the wildcard.

boolean addAll(Collection<? extends E> c);
Copy the code

Refer to the remarks

  1. For reference, Oracle Java documents Unbounded Wildcards and Guidelines for Wildcard Use