Objective:
Java's generic upper and lower bounds are not very well understood, especially like my dish chicken. I've seen it several times ...
A simple system of inheritance
class person{} class extends person{} class extends person{}
Second, generic limit (extends keyword)
public static void upperbound (list<? extends Person> list, person p) { // Correct, because NULL has no type information list.add (null ); // error because the parameter type of list may be a subclass of person Span style= "color: #008000;" >list.add (p); ① successfully get if (list.size () > 0) {person pp = list.get (0
The error at ① is that the parameter type of the List is indeterminate, the parameter type may be a subclass of person, and the subclass collection (List) cannot add elements of the parent class. The test is as follows:
Public Static void Testupperbound () { ArrayList<Student> slist = new arraylist<student>(); New person (); Upperbound (Slist, p); // cannot add success }
How to solve the generic upper limit add problem, you can use the generic method, as follows:
Public Static extends void upperBound2 (list<t> List, T p) { list.add (p); }
Public Static void TestUpperBound2 () { ArrayList<Person> plist = new arraylist<person> (); New Person (); New Student (); UpperBound2 (plist, p); UpperBound2 (plist, s); }
That is, when using the generic upper bound Add method, the collection parameter type and the element parameter type are consistent so that there is no contradiction when adding. Take a look at the UpperBound2 in Eclipse (plist, s); the prompt for this function call is as follows:
As can be seen, the t type eventually resolves to the maximum type of the generic, Student s corresponding upward transformation.
Then say ②, why can we get success? A generic upper limit, at least the type of the upper limit is OK, all of the upper-class subclass can be transformed upward, natural acquisition is not a problem.
Third, the lower limit of the generic type
public static void lowerbound (list<? super Student> list) {person var = new person (); // error, list parameter type may be Student, This will not add the parent class person, so the variable var must be of type student or student subclass list.add (p); ①// correct Student s = new Student (); List.add (s); }
Public Static void Testlowerbound () { ArrayListnew arraylist<person>(); Lowerbound (list); }
① add failure, tells us that the generic lower bound when you add an element using the Add method, the element's parameter type must be a lower or lower subtype. Otherwise, the child class collection is added to the parent class element.
public static void lowerBound2 (list<? super Person> list) {person P = new person (); List.add (P); // get, cannot compile person as = List.get (0 ) ; ①}
Public Static void TestlowerBound2 () { ArrayListnew arraylist<person>(); LowerBound2 (list); }
① failed, let's take a look at eclipse tips what should we do?
The second method changes the type of "as" to "object" and the lower bound of the generic. Consider that the Add (e) method, when correctly added, becomes an object, and when you use the Get (index) method, it is converted to
? The super person type, which may be the person type, or the parent type of person, or even object, executes the person as = List.get (0), then there is a downward transition. There is no guarantee that the downward transformation is safe in Java. So ① cannot be compiled at all.
Iv. the most common application of the upper limit of a generic type
New Arraylist<person>(); ListNew arraylist<student>(); Plist.addall (slist);
V. The most common application of the lower limit of a generic type
New Treeset<student> (new comparator<person>() { @Override public int Compare (person O1, person O2) { return 0; }});
Vi. A comprehensive example of the upper and lower limits of the generic type
Note: Personal nonsense ..., is to combine the above two examples together!
New Treeset<person> (new comparator<person>() { @Override public int Compare (person O1, person O2) { return 0; }}); ListNew arraylist<student>(); ListNew arraylist<worker>(); Set.addall (slist); Set.addall (wlist) ;
Next, look at the generic erase ...
Java generic upper and lower bounds