JAVAクイックエントリー-汎用

19879 ワード

Tips:
汎用型はプログラム設計言語の特性である.プログラマが強いタイプのプログラム設計言語でコードを記述するときに、使用前に示す必要があるいくつかの可変部分を定義できます.さまざまなプログラミング言語は、コンパイラ、実行環境の汎用的なサポートとは異なります.タイプをパラメータ化して、コード多重化を達成し、ソフトウェア開発の生産性を向上させるデータ型です.汎用クラスは参照タイプであり,スタックオブジェクトであり,主にタイプパラメータという概念を導入した.汎用型の定義は主に以下の2種類がある:1.プログラム符号化には、タイプパラメータを含むタイプがあります.すなわち、汎用パラメータはクラスのみを表すことができ、個別のオブジェクトを表すことはできません.(これは現在一般的な定義です)2.プログラム符号化にパラメータを含むクラスの一部.そのパラメータはクラスやオブジェクトなどを表すことができます.(テンプレートと呼ばれることが多い)どの定義を使用しても、汎用パラメータは本当に汎用を使用する場合に示さなければならない.いくつかの強いタイプのプログラミング言語は汎用をサポートし、その主な目的はタイプの安全を強化し、クラスの変換回数を減らすことであるが、いくつかの汎用をサポートするプログラミング言語は一部の目的を達成することしかできない.
上のTipsは汎用型を理解していないのか理解しにくいのか、本章ではコードの形式を使用して、汎用型が何なのかを簡潔に明らかにすることができます.以下に、汎用型を使用していないJAVAコードを書きます.
class Person {
    private int age;

    public void setAge(int age) {
        this.age  = age;
    }

    public int getAge() {
        return this.age;
    }
}

public class Generics {
    public static void main(String args[]) {
        Person p = new Person();
        p.setAge(3);
        System.out.println(p.getAge());
    }
}

上のコードは、setAgeという関数が伝達するパラメータが整数変数ではないと仮定し、「3 years old」という文字列を伝達するには、Personクラスで定義されているint型変数をすべて1つずつStringに変更する必要があります.これは明らかに時間の無駄です.では、汎用型を導入することができます.汎用型とは、クラス内の属性タイプを名前で置き換えることです.intをStringに変更する必要がある場合は、定義を直接変更してすべてのタイプの置換を実現するか、コードの形式で直感的に行うか、上のコードを変更して汎用型を使用すると、次のようになります.
/*    T     (       ,    T),                 */
class Person {
    private T age;

    public void setAge(T age) {
        this.age  = age;
    }

    public T getAge() {
        return this.age;
    }
}

public class Generics {
    public static void main(String args[]) {
        /*       int  String,   <>         */
        Person p = new Person();
        p.setAge("3 years old");
        System.out.println(p.getAge());

        /*      int,        ,     Integer  */
        Person p2 = new Person();
        p2.setAge(3);
        System.out.println(p2.getAge());
    }
}

もちろん、上記ののように2つの汎用型を使用したい場合も可能ですが、例えばが2つのタイプの代わりに使用され、定義時にのような2つのタイプを定義する必要があります.上の印刷プロセスが関数を使用して実現されると、関数パラメータの定義も汎用を使用することができますか?上に伝達されるクラスは彼らの汎用が異なり、1つはで、1つはで、私たちはパラメータに伝達するときにワイルドカードを使用することができます.を参照してください.
class Person {
    private T age;

    public void setAge(T age) {
        this.age  = age;
    }

    public T getAge() {
        return this.age;
    }
}

public class Generics {
    public static void main(String args[]) {
        Person p = new Person();
        p.setAge("3 years old");
        //System.out.println(p.getAge());
        printInfo(p);

        Person p2 = new Person();
        p2.setAge(3);
        //System.out.println(p2.getAge());
        printInfo(p2);

        /*                ,     ,    ,    setAge */
        Person> p3;
        p3 = p;
        p3.getAge();
    }

    /* >                    */    
    public static void printInfo(Person> p) {
        System.out.println(p.getAge());
    }
}

では、形参にも汎用を使わせたいならワイルドカードを使わないでください.いいですか、いいですよ.コードの実現を見てください.
public class Generics {
    public static void main(String args[]) {
        Person p = new Person();
        p.setAge("3 years old");
        //System.out.println(p.getAge());
        printInfo(p);

        Person p2 = new Person();
        p2.setAge(3);
        //System.out.println(p2.getAge());
        printInfo(p2);


        Person> p3;
        p3 = p;
        p3.getAge();

        /*          */
        printInfo2(p);
        printInfo2(p2);
        printInfo2(p3);
    }

    public static void printInfo(Person> p) {
        System.out.println(p.getAge());
    }

    /*                  */
    public static  void printInfo2(Person p) {
        System.out.println(p.getAge());
    }
}

子も親の中の汎用型を使うことができるかどうか、具体的にはコードを見てみましょう.
class Person <T>{
    private T age;

    public void setAge(T age) {
        this.age  = age;
    }

    public T getAge() {
        return this.age;
    }
}

/*        */
class Student<T> extends Person<T> {
}

/*          ,           ,   */
class Student2 extends Person<String> {
}

public class Generics {
    public static void main(String args[]) {
        Person p = new Person();
        p.setAge("3 years old");
        //System.out.println(p.getAge());
        printInfo(p);

        Person p2 = new Person();
        p2.setAge(3);
        //System.out.println(p2.getAge());
        printInfo(p2);


        Person> p3;
        p3 = p;
        p3.getAge();

        /*          */
        printInfo2(p);
        printInfo2(p2);
        printInfo2(p3);

        Student s = new Student();
        s.setAge(10);
        printInfo(s);//  s        Person  

        /*        ,                          */
        Student2 s2 = new Student2();
        s2.setAge("11 years old");
        printInfo(s2);
    }

    public static void printInfo(Person> p) {
        System.out.println(p.getAge());
    }

    /*                  */
    public static  void printInfo2(Person p) {
        System.out.println(p.getAge());
    }
}

もちろん、インタフェースは特殊な親と見なすことができ、もちろん汎用型も使用することができます.以下のようにします.
interface Person <T>{
    public void setAge(T age);
    public T getAge();
}

class Student<T> implements Person<T> {
    T age;

    public void setAge(T age){
        this.age = age;
    }
    public T getAge(){
        return this.age;
    }
}


class Student2 implements Person<String> {
    String age;

    public void setAge(String age){
        this.age = age;
    }
    public String getAge(){
        return this.age;
    }
}

public class Generics {
    public static void main(String args[]) {
        Student s = new Student();
        s.setAge(10);
        printInfo(s);//  s      Person

        /*                   */
        Student2 s2 = new Student2();
        s2.setAge("11 years old");
        printInfo(s2);
    }

    public static void printInfo(Person> p) {
        System.out.println(p.getAge());
    }

    /*                  */
    public static  void printInfo2(Person p) {
        System.out.println(p.getAge());
    }
}

最後に「制限された汎用型」を見てみると、汎用型は上限と下限を定義することができ、まず汎用型の上限を見て、TをNumberクラスまたはそのサブクラスのみと定義し、extemdsで上限を表す.
interface Person <T>{
    public void setAge(T age);
    public T getAge();
}

/*       Integer   float  */
/*         Number   */
class Student<T extends Number> implements Person<T> {
    T age;

    public void setAge(T age){
        this.age = age;
    }
    public T getAge(){
        return this.age;
    }
}


class Student2 implements Person<String> {
    String age;

    public void setAge(String age){
        this.age = age;
    }
    public String getAge(){
        return this.age;
    }
}

public class Generics {
    public static void main(String args[]) {
        /*               String     */
        Student s = new Student();
        s.setAge(10);
        printInfo(s);

        Student2 s2 = new Student2();
        s2.setAge("11 years old");
        printInfo(s2);
    }

    public static void printInfo(Person> p) {
        System.out.println(p.getAge());
    }
    public static  void printInfo2(Person p) {
        System.out.println(p.getAge());
    }
}

汎用の下限を見てみると、TはStringクラスまたはその親クラスのみと定義され、superで下限を表し、superはワイルドカードにのみ使用され、以下のようにします.
interface Person <T>{
    public void setAge(T age);
    public T getAge();
}

//       ,super       
//class Student implements Person {
class Student<T> implements Person<T> {
    T age;

    public void setAge(T age){
        this.age = age;
    }
    public T getAge(){
        return this.age;
    }
}

class Student2 implements Person<String> {
    String age;

    public void setAge(String age){
        this.age = age;
    }
    public String getAge(){
        return this.age;
    }
}

public class Generics {
    public static void main(String args[]) {
        /*             String       */
        Student s = new Student();
        s.setAge("10 years old");
        printInfo(s);

        Student2 s2 = new Student2();
        s2.setAge("11 years old");
        printInfo(s2);
    }

    /*          String  String         */
    public static void printInfo(Person super String> p) {
        System.out.println(p.getAge());
    }

    public static  void printInfo2(Person p) {
        System.out.println(p.getAge());
    }
}