T and java generics wildcards?
The basic usage of a generic
Java5 from the start, java began to introduce generics. In the absence of generics, to read from the collection of each object must be converted, if someone accidentally inserted the wrong type of object, the conversion process in the run-time error occurs.
Once you have generics, you can tell the compiler which object type for each set of acceptance. The compiler automatically converts your insertion, whether inserted inform the wrong type of object pancake ah compile time.
definition
· 1 defined in the class, followed by the class name
public class TestClassDefine<T, S extends T>{}
Define a generic T, S, T and S inheritance
· 2 defined behind the character decoration method, immediately behind the modifier (public)
public <T, S extends T> T testGenericMethodDefine(T t, S s){}
Define a generic T, S, T and S inheritance
Operating principle
java generics is run by wiping, that will not take effect during the operation of the code, compile only take effect.
List<String> stringArrayList = new ArrayList<String>();
List<Integer> integerArrayList = new ArrayList<Integer>();
Class classStringArrayList = stringArrayList.getClass();
Class classIntegerArrayList = integerArrayList.getClass();
if(classStringArrayList.equals(classIntegerArrayList)){
Log.d("泛型测试","类型相同");
}
Output Results: D / generic test: same type.
This sentence summarized: the generic type to logically as a plurality of different types, are actually the same basic type.
Two? PECS law
Parameterized type is unchanged.
For any two distinct types? Type1 and Type2 terms, List <Type1> is neither a List <Type2> subtype, nor is it a super-type. That while the String? Subtype of Object class, but List <String> has never been? List <Object> subtype
We define a class Stack:
public class Stack<E> {
public Stack();
public void push(E e);
public E pop();
public boolean isEmpty();
}
If we try to define a pushAll method, in order to make it into a series of elements in the stack
public void pushAll(Iterable<E> src) {
for (E e : src) {
push(e);
}
}
In compile this method is correct, consider the definition of a? Stack <Number>, and call pushAll, parameter passing is? Integer type, according to the logic that this is possible because Integer is a subclass of Number.
Stack<Number> numberStack = new Stack<>();
Iterable<Integer> integerIterable = new ArrayList<Integer>();
numberStack.pushAll(integerIterable);
But this can not be compiled by
this time we wildcard? It comes in handy
public void pushAll(Iterable<? extends E> src) {
for (E e : src) {
push(e);
}
}
Input Parameter Type pushAll should not be? Iterable interface to E, but should be a subtype of Iterable E interface. Wildcard type Iterable <? Extends E> formal mean.
Calls can already be normal.
Now suppose you want to write a popAll methods and pushAll correspondence. That the element is ejected from the stack, and collected in the collection specified:
public void popAll(Collection<E> dst) {
while (!isEmpty()) {
dst.add(pop());
}
}
Similarly, if a stack element type and the target set an exact match, then compile and run well.
Now suppose you have a Stack <Number> and object types of variables, Pops an element from the stack stored in the object, press the error should say
can see or get an error similar to the first time pushAll: Collection <Number> not Collection <Object> subtype.
We can be modified as follows:
public void popAll(Collection<? super E> dst) {
while (!isEmpty()) {
dst.add(pop());
}
}
Then we would not have the above code the error. Input Parameter Type popAll E should not be set, but rather is a collection of some kind of extra class E.
The conclusion is clear: in order to obtain maximum flexibility to use wildcards to represent the type of the input parameters of the producer or the consumer.
PECS represents producer-extends, consumer-super
if parameterized type represents a producer T, on the use? <Extends T?>;? If he said a consumer T, on the use of <super T?>.
And remember: the Comparable and Comparator is a consumer
And three T? More scenes
1. Note that we can not add any elements to the List <?>, In addition to null, even with the upper and lower boundaries too.
2, try not to use wildcard characters in the return value, as this will force users to use wildcards in the client code, if the user must consider the wildcard type, greatly increase the possibility of error api
3, is always Comparable <? Super T> takes precedence over Comparable <T>, is always Comparator <? super T> takes precedence over the Comparator <T>
4, there is a problem worthy of discussion
public static <E> void swap(List<E> list, int i, int j);
public static void swap(List<?> list, int i, int j);
In javaAPI, the second is better, because it does not need to consider the type of parameters, but can freely pass the type of value list.
In general, if the type parameters appear only once in the process of life, you can replace it with a wildcard.