List<Integer> bigs = Arrays.asList(100,200,300); assert sumInteger(bigs) == sum(bigs); assert sumInteger(bigs) != sumInteger(bigs);
class Lists { public static <T> List<T> toList(T[] arr) {...} }
class Lists { public static <T> List<T> toList(T... arr) {...} } * The type parameter to generic method is inferred,but it may also be given explicitly,as is the following examples:
List<Integer> ints = Lists.<Integer>toList(); List<Object> objs = Lists.<Object>toList(1,"two");
* **List<Integer>** is not a subtype of **List<Number>**,nor is **List<Number>** a subtype a subtype of **List<Integer>**;Arrays behave quite differently,with them,**Integer[]** is a subtype of **Number[]**. * Wildcards with extends
interface Collection<E> { ... public boolean addAll(Collection<? extends E> c); ... }express
The phrase "**? extends E**" means that it is also OK to add all members of a collection with elements of any type that is a subtype of E. In general, if a structure contains elements with a type of the form ? extends E, we can get elements out of the structure, but we cannot put elements into the structure. * Wildcards with super
public static <T> void copy(List<? super T> dst, List<? extends T> src) { for (int i = 0; i < src.size(); i++) { dst.set(i, src.get(i)); } }app
The quizzical phrase "**? super T**" means that the destination list may have elements of any type that is a supertype of T. #### The Get and Put Principle The Get and Put Principle: use an extends wildcard when you only get values out of a structure, use a super wildcard when you only put values into a structure, and don’t use a wildcard when you both get and put. public static <T> void copy(List<? super T> dest, List<? extends T> src) * Wildcards Versus Type Parameters
interface Collection<E> { ... public boolean contains(Object o); public boolean containsAll(Collection<?> c); ... }ide
The type "**Collection<?>**" stands for: `Collection<? extends Object>` Extending Object is one of the most common uses of wildcards, so it makes sense to provide a short form for writing it. #### Restrictions on Wildcards Wildcards may not appear at the top level in class instance creation expressions (new) in explicit type parameters in generic method calls, or in supertypes (extends and implements). ``` List<?> list = new ArrayList<?>(); // compile-time error Map<String, ? extends Number> map = new HashMap<String, ? extends Number>(); // compile-time error
** Only top-level parameters in instance creation are prohibited from containing wildcards. Nested wildcards are permitted. Hence, the following is legal:**oop
List<List<?>> lists = new ArrayList<List<?>>(); lists.add(Arrays.asList(1,2,3)); lists.add(Arrays.asList("four","five")); assert lists.toString().equals("[[1, 2, 3], [four, five]]");
One way to remember the restriction is that the relationship between wildcards and ordinary types is similar to the relationship between interfaces and classes—wildcards and interfaces are more general, ordinary types and classes are more specific, and instance creation requires the more specific information. Consider the following three statements:
List<?> list = new ArrayList<Object>(); // ok List<?> list = new List<Object>() // compile-time error List<?> list = new ArrayList<?>() // compile-time error