List<? >
和 List<Object>
The difference between
The difference between:
List<? >
The elements of a variable can only be read, not written (can be insertednull
Elements)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 List
List<? >
和 List
The 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:
- You must use the original type in class literals,
List.class
,String[].class
和int.class
That’s right, butList<? >.class
List<String>.class
Is wrong. - 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:
- 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
- The List variable (out) used for writing is bound using super
- 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
boolean addAll(Collection<? extends E> c);
Copy the code
Refer to the remarks
- For reference, Oracle Java documents Unbounded Wildcards and Guidelines for Wildcard Use