Java Generics Learning and Practice (4)

Source: Internet
Author: User

Introduction

The first three sections describe common declarations and uses of generics, which can be declared on a class, or declared on a single method, and summarized in each case. Here's how to learn the generic extension.

With the previous runnable interface, Buick class, Ford class, Driver class, add a new car container class Carcontainer

First edition

The code is as follows:

Public interface Runnable {public    void run ();
public class Buick implements Runnable {        @Override public    void Run () {        System.out.println ("Buick Run");    } Public        void AutoRun () {        System.out.println ("Buick Auto-run");}    }
public class Ford implements Runnable  {        @Override public    void Run () {        System.out.println ("Ford Run") ;    }        public void Fly () {        System.out.println ("Ford Fly");}    }
<pre name= "code" class= "Java" >public class Driver<t extends runnable> {        private T car;        public void Drive (T car) {        This.car = car;        System.out.println ("I am driving a" + car);        Car.run ();    }        Public T Getdrivingcar () {        return car;    }}
public class Carcontainer<e extends runnable> {    private list<e> container = new arraylist<e> (); 
   public void Add (E e) {        container.add (e);    }        public void Add (driver<e> producer) {        container.add (Producer.getdrivingcar ());    }        public static void Main (string[] args) {        carcontainer<runnable> container = new Carcontainer<runnable> ( );        Buick Buick = new Buick ();        Container.add (Buick);        driver<runnable> Driver = new driver<runnable> ();        Driver.drive (Buick);        Container.add (driver);    }}

The first three classes do not say much, do not understand, please refer to the previous three. Next to the Carcontainer class, the Add method receives a generic E-type object and adds a new car to the container. Another overloaded Add method receives the Driver<e> parameter, gets to the Drivingcar, and adds it to the container.

The use of the two add is demonstrated in the main static method, respectively. First the first Add method to use, because the Buick class implements the Runnable interface, Container.add (Buick) Such invocation is no problem; see the second Add method use: First Driver.drive (Buick) also no problem, the principle of the same And then look at Container.add (driver), because the container element type is the Runnable interface, and the driver element type is the Runnable interface, the type is exactly the same, so running the next program is no problem, it looks good.

If there is a driver<buick>, please think about this call to see the line does not

        driver<buick> Driver = new driver<buick> ();        Driver.drive (Buick);        Container.add (driver);
The result is no, the following error is prompted at compile time:

The method Add (Runnable) in the type carcontainer<runnable> are not applicable for the arguments (driver<buick> )

Logically, this invocation should be possible because Buick implements the Runnable interface, but in fact it does not. Fortunately, there is a workaround. Java provides a special type of parameter, called a restricted wildcard type (bounded wildcard type), to handle a similar situation. Our idea is that the second Add method receives a parameter that is "driver of a subtype of e" and can be passed driver< Extends e> implementation.? represents any unknown type, with an additional extends E restriction, indicating that the unknown type must be a subclass of E or itself. The modified code is as follows:

Second Edition

    public void Add (driver<? extends e> producer) {        container.add (Producer.getdrivingcar ());    }
After this modification, the demo program can be compiled and run normally, indicating that this is type-safe.

The first occurrence of a wildcard associated with generics, which represents an unknown type, is briefly described below.

?

? Typically appears on a method parameter, representing an unknown type. Note the difference from the E in the generic declaration. Generic E is equivalent to a type placeholder that can appear in multiple places in a class and means that the specific types in the future are the same (for example, generics in the driver class and Carcontainer), whereas, for a specific type that is unknown, the class appears in more than one place. There is no association.

? support <? Extends parent> usage, which means that the unknown type must be a subclass or itself of the Parent, is similar to <e extends parent> meaning in generics.

? also supports <? Super child> usage, which means that the unknown type must be a superclass or itself of child, and this usage does not exist in generics (because it is meaningless), please note.


The above summary mentions <? Super child> usage, next add to learn about Super's usage scenarios.

For the Carcontainer class, which corresponds to the Add method, we add a pop method, as follows:

    public void Pop (set<e> consumer) {        Consumer.add (Container.remove (Container.size ()));    }
Receives the collection class consumer parameter, removes the last element from the container in the method body and joins the consumer. Examples of use are:

        carcontainer<runnable> container = new carcontainer<runnable> ();        Buick Buick = new Buick ();        Container.add (Buick);                set<runnable> consumer = new hashset<runnable> ();        Container.pop (consumer);
If you have another set<object> consumer = new Hashset<object> (), if you follow the above call, a compilation error will occur:

The method Pop (set<runnable>) in the type carcontainer<runnable> are not applicable for the arguments (set<o bject>)

Our idea is that the pop receives the parameter application is "E of some kind of superclass set", through the "and Super keyword combined use just can achieve this purpose, namely set<?" Super E>, the modified code is as follows:

Third edition

    public void pop (set<? Super E> consumer) {        Consumer.add (Container.remove ());    }
After the modification, set<object> consumer is supported in the call mode.

With the use of the extends or Super keyword on the method parameters, you get the maximum flexibility of the API.

So under what circumstances should you use the extends keyword, and under what circumstances should you use the Super keyword. There is a principle called pecs, namely Producer-extends,consumer-super.

Pecs means that if a generic parameterized type represents an e producer, the < is used. Extends e>; if it represents an E-consumer, use <? Super e>. In the above example, the producer parameter of add produces an instance of E for Carcontainer use, so producer the corresponding type is driver<? The consumer parameter of the extends E>;pop is consumed by the Carcontainer consumption E instance, so the consumer parameter corresponds to the type set<? Super e>. If the argument is the producer and the consumer, wouldn't it be appropriate to use wildcards? Because you need a strict type match, that is, using set<e> directly

The above wildcard characters for generics, extends, and super are used in reference to the effective.java_2 Chinese version. pdf, because of the limited level, we may not understand. You are welcome to ask questions.

About this practice demo, temporarily not used in the project, supplemented later

Conclusion

About generics learning and practice to this end, a total of four sections, thank you for your attention. When we have time, I want to learn the design pattern with everyone, and I think this is a required course for every Java programmer. Please expect

Java Generics Learning and Practice (4)

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.