Java generics, wildcard characters? Doubts

Source: Internet
Author: User
Tags comparable

Java generic wildcard? Category: Java 2014-05-05 15:53 2799 people read reviews (4) Favorites report generic wildcard upper bound unbounded directory (?)  [+] Turn from: Http://www.linuxidc.com/Linux/2013-10/90928.htmT have type? Unknown type one, the upper bound of the wildcard if you know that list<cat> is not list<anilmal> subtype, then you need to find a solution for him, is animaltrianer.act () Methods become more generic (both accept list<animal> types and accept parameters such as list<cat>). The solution in Java is to use the wildcard character "? ", specifically to Animaltrianer, is to change the method to act (LIST&LT; Extends Animal> list), among them "? "is a wildcard, and"? Extends Animal "is a wildcard?" "The upper bound is animal, in other words,"? Extends Animal "can represent Animal or its subclasses, and can not represent Animal's parent class (such as Object) because the upper bound of the wildcard is Animal.  As below, for the improved Animaltrianerpublic class Animaltrainer {public void Act (LIST&LT;? extends animal> List) {for (Animal Animal: List) {animal.eat ();}}} To test again, as below, found that test 2 can be compiled by: public class Testanimal {public static void main (string[] args) {Animaltrainer Animaltrainer = New Animaltrainer ();//test 1list<animal> animallist = new arraylist<> (); Animallist.add (New Cat ("CAT1")); Animallist.add (New Bird ("Bird1")) Animaltrainer.act (animallist);//Can be compiled//test 2list<cat> catlist = new ArRaylist<> (); Catlist.add (New Cat ("CAT2")) Catlist.add (New Cat ("CAT3")); Animaltrainer.act (catlist);//can also be compiled }} After the above analysis, you can know that list<animal> and list<cat> are list< Extends animal> sub-type, similar to list<bird>,list<magpie> is also list< Extends subtype of animal>. As summarized below, for the upper bound of the wildcard, there are the following basic rules: (assuming the given generic type is G, (such as list in list<e>), two specific generic parameters x, y, where y is the subclass of X (e.g. animal and cat above) g<? Extends y> is g< Extends subtype of x> (e.g. list<?) Extends cat> is list< The subtype of the extends animal>). G<x> is g< Extends X> sub-type (such as list<animal> is list<? Extends animal> sub-type) g<?> and g<? Extends object> equivalent, such as list<?> and list< Extends objext> equivalent. Learning here, you may encounter some doubts, or things can not understand the place, first observe the following two snippets of code, to determine whether it is feasible?? public void Testadd (list<? extends animal> List) {//.... Other logical List.add (new Animal ("Animal")), List.add (New Bird ("Bird")), List.add (New Cat ("Cat")); list<? Extends animal> list = new arraylist<> () List.add (New Animal ("Animal")); List.add (New Bird ("Bird")); List.add ( New Cat ("Cat"); First analyze as follows: because"? Extends Animal "can represent Animal or its subclasses (BIRD,CAT), the above operation should be feasible. In fact, "No", that is, cannot be compiled. Why?? Before you explain, re-emphasize the rules you already know: Only animal class objects and their subclass objects (such as Cat and Bird objects) can be added to the list<aimal> list in list<bird> Can only add the bird class and its subclass objects (such as Magpie), you cannot add animal objects (not bird subclasses), similar to list<cat> and list<magpie> can only add cat and bird objects (or their subclass objects, but this is not listed). Now look back at the Testadd () method, we know that list<animal>, list<cat, etc. are list< Extends subtype of animal>. Assuming that the passed-in parameter is List<animal&gt, then the three "add" operations of the first code are feasible, but what if it is list<bird>? Only the second "add" can be executed, and assuming that the incoming list<tiger> (Tiger is imaginary and can be considered a subclass of cat), three "add" operations cannot be performed. Now on the other hand, to give Testadd a different parameter, three "add" operation can raise the type incompatibility problem, and the parameters passed in is unknown, so Java in order to protect the type consistent, prohibit to list< Extends animal> add any object, but you can add null, that is, list.add (null) is possible. With the foundation mentioned above, it is not difficult to understand the second piece of code, because list< Extends type of animal> "? Extends Animal "cannot be determined, it can be animal,bird or cat, so to protect the consistency of its type, you cannot add any objects to the list, but you can add null. First summed up as follows: Can not go to list< Extends animal> add any object, except NULL. Another point of caution is that in list< Extends animal> can be Animal class object or Bird object (just some kind of object), conversely, in list< Extends Animal> LiST is the animal object, that is, bird is also animal object, Cat is also the animal object (in the Java language is the subclass can point to the parent class, the parent class cannot point to the subclass), then all the methods in the animal can be called, as follows: for ( Animal animal:list) {animal.eat ();} Second, the lower bound of the wildcard character has the upper bound of the wildcard character, which naturally has the lower bound of the wildcard character. You can define the lower bound of the wildcard character list<? Super Bird&gt, where "Bird" is the lower bound of the wildcard character. NOTE: You cannot declare both the upper and lower bounds of a generic wildcard declaration at the same time. Before we go into the details, let's look at the rules for using wildcards--for the upper bounds of wildcards, there are several basic rules: (assuming a given generic type is g, such as list in list<e>), two specific generic parameters x, Y, Where Y is the subclass of X (as on Animal and cat)) g<? Super x> is g<? Super Y> subtype (e.g. list<?) Super animal> is list<? Super Bird> subtype). G<x> is g< The sub-type of super x> (e.g. list<animal> is list<? Super Animal> sub-type) Now look at the following code to determine if it is logical: public void Testadd (LIST&LT;? Super Bird> List) {list.add (New Bird ("Bird") ); List.add (New Magpie ("Magpie"));} list<? Super Bird> list = new arraylist<> (), List.add (New Bird ("Bird")), List.add (New Magpie ("Magpie")), List.add (new Animal ("Animal")); look at the first piece of code, its analysis is as follows, because "? Super Bird "represents Bird or its parent class, and Magpie is a subclass of Bird, so the appeal code cannot be compiled. And the fact is "line", why? 2? Before troubleshoot, to emphasize a point of knowledge, subclasses can point to the parent class, that is, bird is also the animal object. Now consider all possible arguments passed into the Testadd (), which can be LIST&LT Bird>,list<animal&gt, or list<objext>, and so on, found that the type of these parameters is Bird or its parent class, so we can see that Bird, Magpie as Bird objects, you can also Bird, Magpie as animal objects, similar to object objects, and finally found these added to List< The objects in the Supe bird> list are all of the same class objects (test 1, as mentioned at the beginning of this article), so the Testadd method is logical and can be compiled. : Now take a look at the second code for the second to third line of code as explained above, as for the last line "List.add (New Animal (" Animal ")" is not compiled, why?? In order to protect the consistency of the type, because "? Super Bird "can be animal, or it can be an object or other Bird parent class, because cannot determine its type, also cannot go to list< Super Bird> Add any parent object of Bird. Now that the parent object cannot be determined, how do I traverse the list<? Super bird>? Because object is the root class of all classes, you can use object to traverse it. But it seems to have little meaning. for (Object object:list) {//...} That "? Super Boundingtype "can be applied in what place?? “? Super Boundingtype "is a relatively wide application, but it is mixed. Here's a simple example. First assume that there are the following two Student and Collegestudent, in which Collegestudent inherits Student, as follows: public class Student implements Comparable<student >{private int id;public Student (int id) {this.id = ID;} @Overridepublic int compareTo (Student o) {return (id > O.id)? 1: ((ID < o.id)? -1:0);}} public class Collegestudent extends Student{public collegestudent (int id) {super (ID);}} First of all, according to theirThe ID sorts them (note that this is the sort of array object), and the design method is as follows, (number of elements in N exponential group): public static <t extends Comparable<? Super t>> void Selectionsort (t[] a,int N) first understand the meaning of this method, first <t extends comparable<t>> Specifies that the object in the array must implement the comparable interface, COMPARABLE&LT; Super t> indicates that if the parent implements the comparable interface, it itself is not implemented, such as collegestudent. First assume there is an array of collegestudent, as follows: collegestudent[] stu = new collegestudent[]{new Collegestudent (3), New Collegestudent (2), n EW Collegestudent (5), New Collegestudent (4)}, and the execution method Selectionsort (stu,4) are fully accessible. If the Selectionsort method is defined as follows: public static <t extends comparable<t>> void Selectionsort (t[] a,int N) The method Selectionsort (stu,4) cannot be executed because Collegestudent does not implement the Comparable<collegestudent> interface. In other words, "? Super T "makes the Selectionsort method more generic. Selectionsort the implementation of the complete code can refer to the end of this article. Third, the unbounded wildcard know the upper bound and the lower bound of the wildcard, in fact, it is also equivalent to know the unbounded wildcard, without any modification can be, a single "? ”。 such as List<?>, "? "Can represent any type," arbitrary "is an unknown type.  Unbounded wildcard characters are typically used in the following two cases: 1, when the method is using the original Object type as a parameter, as follows: public static void Printlist (List<object> List) {for (object elem:   List) System.out.println (Elem + ""); System.out.println ();} You can choose to implement the following instead: public static void Printlist (List<?> List) {for (Object elem:list) System.out.print (Elem + ""    ); System.out.println ();} This can be compatible with more output, not simply List<object&gt, as follows:list<integer> Li = Arrays.aslist (1, 2, 3); list<string> ls = arrays.aslist ("One", "one", "three");p Rintlist (LI);p rintlist (LS); 2. The business logic of the method body defined is independent of the generic type, such as List.size,list.cleat. In fact, the most common is class<?&gt, because class<t> is not dependent on T. The last reminder is that,list<object> and list<?> are not the same,list<object> as the list<?> subclasses.  There is no way to add any objects to the list<?> list, except NULL. Appendix: Selectionsort Code Implementation: (If you need to implement a better output, it is best to override the student ToString method) public class Sortarray {//For a set of array objects using the insertion sort, n number of elements of the exponent group public static <t extends Comparable<? Super t>> void Selectionsort (t[] a,int N) {for (int index = 0; index < n-1; index++) {int indexofsmallest = Getin Dexofsmallest (a,index,n-1); swap (a,index,indexofsmallest);}} public static <t extends Comparable<? Super t>> int getindexofsmallest (t[] A, int first, int last) {T minValue = A[first];//Assuming that the first is minvalueint indexofmin = firstly;//get minValue subscript for (int index = primary + 1; I Ndex <= last; index++) {if (A[index].compareto (MinValue) < 0) {MinValue = A[index];indexofmin = Index;}} return indexofmin;} public static void Swap (object[] A,int first,int second) {Object temp = A[first];a[first] = A[second];a[second] = temp;} public static void Main (string[] args) {collegestudent[] stu = new Collegestudent[]{new collegestudent (3), new Collegestud ENT (2), New Collegestudent (5), New Collegestudent (4)};selectionsort (Stu, 4); for (Student Student:stu) { SYSTEM.OUT.PRINTLN (student);}}}

Java generics, wildcard characters? Doubts

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.