This question is aimed at "? Super t "and" Extend T ",I choose a classic example from the book to show you. If you don't understand it, then you can refer to the following books, take your time and experience it step by step!
"? Super T and "?" Extends T "is a common wildcard in java, which has different usages.
Also, super and extends are not superclasses and inheritance in java class relations, they are the lower and upper limits of wildcards.
Let's look at the advanced usage of wildcards:
In this section, let's consider some advanced uses of wildcards. We have seen several examples of reading upper-bound wildcards from data structures. Now consider the opposite situation, just write the data structure.
An interface receiver is a simple example of this situation.
Interface receiver & ltT>{
Invalid flushing (t t);
}
We can imagine it being used as the following code. The method writeAll () is designed to refresh all elements of the collection coll to receive snk and return the last refreshed element.
Public static & ltT>T writeAll (set<T & gtcoll, Sink & ltT & gtsnk) {
T last = null
for (T t : coll) {
last = t;
Snk.flush (the last one);
}
Finally return;
}
Water tank & ltObject & gts;;
Collect & lt string & gtcs;;
String str = writeAll(cs,s); //Illegal call! !
As mentioned above, the call to writeAll () is illegal because there are no valid type parameters to infer. String and Object are not suitable t types, because the elements of Collection and Sink must be of the same type.
We can solve this problem by using wildcards to modify the method signature of writeAll (), as shown below:
& ltT>T writeAll (set Extended T & gtcoll, Sink & ltT & gtsnk) {…}
String str = writeAll(cs,s); //can be called, but the return value type is wrong.
This call is now legal, but the assignment generated an error, because the inferred return value type is Object, because t matches the Sink's type Object.
The solution is to use a finite wildcard that we haven't seen yet: a wildcard with a lower limit. Grammar? Super T represents an unknown parent class of T (or T itself). Is this for us? Extending t means that the unknown subclasses of t are corresponding.
& ltT>T writeAll (set<T & gtcoll, sink Super T & gtsnk) {…}
String str = writeAll(cs,s); //Yes! ! !
Using this syntax, this call is legal, and the inferred t is String, which is exactly what we want.
Now let's look at a more realistic example. A cup of Java coffee. Practical tree set
TreeSet (comparator & ltE>c)
The comparator interface is the core:
Interface comparator & ltT>{ int compare(T fst, tsnd); }
Suppose we want to create a tree set.
TreeSet (comparator Super E>c)
This allows any available comparator to pass in.
As the last example of using the lower-bound wildcard, let's look at the Collections.max () method, which returns the largest element in the collection.
Now, in order for max () to work, all elements in the incoming collection must implement the Comparatable interface. In addition, they must all be comparable. The first attempt is:
Public static & ltt extension comparability & ltT>& gtT max (collection & ltT & gtcoll)
In other words, the parameters of the method are a set of t, which can be compared with itself. This restriction is too strict.
Why? Consider a type that can be compared with any object:
Class Foo implements a comparable & ltObject & gt{...} ...
Collection & ltFoo & gtcf =...;;
collections . max(cf); //It should work.
Each element in a cf can be compared with other elements in each cf, because each such element is a Foo and can be compared with any object or another Foo.
However, using the above method signature, we found that the call was rejected. The inferred type must be Foo, but Foo does not implement a comparable interface.
There is absolutely no need to compare with yourself. What is needed is that T can be compared with one of its parent classes, which leads to the complexity of the actual method signature of: (note: Collections.max (), which we will discuss in section 10. )
Public static & ltt extensions are comparable to < Super T>& gtT max (Collection & ltT & gtcoll)
This inference is valid for most people who want Comparable to be applicable to any type of usage: you should always use comparable.
In short, if you have an API that only uses the type parameter t as a parameter, it should be the same as the lower limit wildcard (? The benefits of super t). Conversely, if the API only returns t, you should use the upper limit wildcard (? Expand t) Give your customers more flexibility.
(Original: This reasoning applies to almost any usage of comparable, and it applies to any type: you always want to use comparable.
Generally speaking, if you have an API that only uses the type parameter t as a parameter, then its use should make use of the lower bound wildcard (? Super t). Conversely, if the API only returns t, then by using the upper limit wildcard (? Expand t). )。
If you want to know more about java generics, then
I suggest you have a look:
Chinese link address:/J2SE/1.5/pdf/generics-tutorial.pdf.