Java Wildcard FAQ

Source: Internet
Author: User
Tags comparable

T has type

? Unknown type

first, the upper bound of a wildcard character

Since it is known that list<cat> is not a list<anilmal> subtype , it is necessary to find a solution for him, the Animaltrianer.act () method becomes more general ( You can accept either the list<animal> type or the list<cat> parameters . The solution in Java is to use the wildcard character "? ", specifically to Animaltrianer, is to change the method to Act (LIST< 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 , not the parent class of Animal (such as Object), because the upper bound of the wildcard is Animal. As below, for the improvement after the Animaltrianer

 Public class Animaltrainer {    publicvoidextends animal> list} {        for  (Animal animal:list) {            animal.eat ();     }}}

To test it again, as below, we find that test 2 can be compiled by:

 Public classTestanimal { Public Static voidMain (string[] args) {Animaltrainer Animaltrainer=NewAnimaltrainer (); //Test 1List<animal> animallist =NewArraylist<>(); Animallist.add (NewCat ("CAT1")); Animallist.add (NewBird ("Bird1"));    Animaltrainer.act (animallist); //can be compiled by//Test 2list<cat> catlist =NewArraylist<>(); Catlist.add (NewCat ("Cat2")); Catlist.add (NewCat ("Cat3"));        Animaltrainer.act (catlist); //can also be compiled by    }}

After the above analysis, you can know that list<animal> and list<cat> are list<? extends animal> subtypes , similar to list<bird> ,list<magpie> is also list< Extends subtype of animal> .

As summarized below, for the upper bounds 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 voidTestadd (list<?extendsAnimal>list) {        //.... Other LogicList.add (NewAnimal ("Animal")); List.add (NewBird ("Bird")); List.add (NewCat ("Cat")); } List<?extendsanimal> list =NewArraylist<>(); List.add (NewAnimal ("Animal")); List.add (NewBird ("Bird")); List.add (NewCat ("Cat"));

The first analysis is 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: , in list<bird> Can only add the bird class and its child class 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 list<animal>, list<cat>, etc. are list< Extends subtype of animal>. Assuming that the passed-in parameter is List<animal>, 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 incoming parameters are 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 basis mentioned above, it is not difficult to understand the second piece of code, because list< extends animal> type "? 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.

To summarize as follows: cannot go to list<? extends animal> add any object, except null.

Another point to note is that in list<, extends animal> can be Animal class objects or bird objects (just some kind of object), conversely, in list<? extends animal> List of all is animal object, that is bird is also animal object, Cat is also 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

Now that you have the upper bound of the wildcard, you naturally have the lower bound of the wildcard character. You can define the lower bound of the wildcard character list< Super bird>, 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 (e.g. animal and cat above))

    • g<: Super X> is G<, the sub-type of Super y> (such as list<? Super Animal> is the subtype of list<? Super bird>).
    • g<x> is g<, the subtype of Super x> ( e.g. list<animal> is list<

Now look at the following code to determine if it is logical:

 Public void Super bird> list) {        List.add (new Bird ("Bird"));        List.add (new Magpie ("Magpie"));    ListSupernew arraylist<>(); List.add (new Bird ("Bird") ); List.add (new Magpie ("Magpie")); List.add (  new Animal ("Animal"));//can ' t compile

Look at the first piece of code, which is analyzed 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? ?

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 Testadd (), which can be list<bird>,list<animal>, or list<objext>, and so on, to find that the type of these parameters is Bird or its parent class. Then we can see, the bird, magpie as bird objects, can also be bird, magpie as animal objects, similar can be seen as object objects, and finally found these added to the 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 is interpreted as above, as for the last line "List.add (Newanimal (" 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.

Since the parent object cannot be determined , how to traverse list<? Super Bird>? Because object is the root class of all classes, you can traverse it with Object . 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 Implements Comparable<student> {        privateint  ID;    @Override    publicint  compareTo (Student o) {        return (ID > O.id)? 1: ((ID < o.id)? -1:0);    }          Public String toString () {        return ' student, and id = ' + ID;    }}

 Public class extends student{    public collegestudent (int  ID) {         Super(ID);}    } 

They need to be sorted based on their ID (note that this is a sort of array object), and the design method is as follows (the number of elements in the N exponential group):

 Public Static extends 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< Super t> indicates that if the parent implements the comparable interface, it itself is not implemented, such as collegestudent. First assume that there is an array of collegestudent, as follows:

New collegestudent[]{   new collegestudent (3),new collegestudent (2),     New Collegestudent (5),new collegestudent (4)};

The execution method Selectionsort (stu,4) is fully accessible. If the Selectionsort method is defined as follows:

 Public Static 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> port. 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.

three, unbounded wildcard characters

Know the upper and lower bounds of the wildcard, in fact, it is also equivalent to know the unbounded wildcard , without any modification can be, a single "? ”。 Like List<?>, "? "Can represent any type," arbitrary "is an unknown type. Unbounded wildcard characters are typically used in the following two scenarios:

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 ();}

You can choose to implement the following:

 Public Static void printlist (list<?> List) {    for  (Object elem:list)        + "");    System.out.println ();}

This can be compatible with more output, not simply List<object>, 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. Thebusiness logic of the method body defined is independent of the generic type , such as List.size,list.clear. In fact, the most common is class<?>, because class<t> is not dependent on T.

The last reminder is that ,list<object> and list<?> are not equal ,list<object> is a subclass of List<?> . There is no way to add any objects to the List<?> list, except null.

Appendix: Selectionsort Code Implementation: (Best to rewrite Student's ToString method if you need to implement better output)

 Public classSortarray {//applying an insert sort to a set of array objects, the number of elements of the N exponential group     Public Static<textendscomparable<?SuperT>>voidSelectionsort (t[] A,intN) { for(intindex = 0; Index < n-1; index++) {            intIndexofsmallest = Getindexofsmallest (a,index,n-1);        Swap (a,index,indexofsmallest); }    }         Public Static<textendscomparable<?SuperT>>intGetindexofsmallest (t[] A,intFirstintLast ) {T MinValue= A[first];//Suppose the first one is MinValue        intIndexofmin = First;//get the subscript of MinValue         for(intindex = first + 1; Index <= last; index++) {            if(A[index].compareto (MinValue) < 0) {MinValue=A[index]; Indexofmin=index; }        }        returnindexofmin; }         Public Static voidSwap (object[] A,intFirstintsecond) {Object temp=A[first]; A[first]=A[second]; A[second]=temp; }         Public Static voidMain (string[] args) {collegestudent[] Stu=Newcollegestudent[]{NewCollegestudent (3),                NewCollegestudent (2),                NewCollegestudent (5),                NewCollegestudent (4)}; Selectionsort (Stu,4);  for(Student student:stu) {System.out.println (Student); }    }}

A collection with wildcards is restricted

See the original: http://blog.csdn.net/baple/article/details/25056169

Java Wildcard FAQ

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.