あなたは、Javaのジェネリックとの記事、最も包括的な一般的な教育、それの歴史をお読みください。

慎重にこれを読んで、あなたはジェネリックの新しい理解を持っていることを確認し、そうでない場合は、私を打つために、ネットワークケーブルに従ってください。

アウトライン

Baiduの百科事典の下の参考答え

ジェネリック医薬品はされている言語プログラミング 1プロパティを。プログラマは強く型付けされたプログラミング言語でコードを書く時間の可変部分を定義することができ、これらの部分は、指定された使用前になされなければなりません。プログラミング言語とそれらの様々なコンパイラ、オペレーティング環境では、ジェネリック医薬品のための同じサポートはありません。型のパラメータは、データ・タイプ・コードの再利用は、ソフトウェア開発の生産性を向上させる達成します。ジェネリッククラスは参照型、ヒープオブジェクト、型パラメータの概念を中心に紹介しています。

私の理解では、次のとおりです。一般的なタイプは、明確なオブジェクトの特殊なタイプを作成するための延期またはクリアするために行く前にメソッドを呼び出すことにあります。

パラメータ化された型は、型は、オブジェクト<データタイプ>と同様の基準型であり、基本的なタイプが存在することができないパラメータとして渡されます。

例えば:

Object<Integer>  //true
Object<int> //false
复制代码

なぜジェネリックデータ型は、それが基本的な型にすることはできませんがありますか?

仮想マシンは、オブジェクトのジェネリック型に取り除くことができますので、コンパイル時には、基本的なないタイプが基本タイプではないタイプの、汎用的なデータ型をオブジェクト。

なぜ使用のジェネリックそれ?

ジェネリック医薬品の導入のJava言語の利点は、安全で簡単です。ジェネリック医薬品のメリットは、コンパイル時の型安全でチェックされ、すべてのキャストは、コードの再利用性を向上、自動および暗黙的です。

それは重要であり、たとえば、エラーの機会を減らし、強制転換を排除することです。

public class Test {
    public static void main(String[] args){
        List list = new ArrayList();
        list.add("1"); 
        list.add(1);
        int i = (int)list.get(0); // java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
        int j = (int)list.get(1);
    }
}
复制代码

addメソッドリストはObject型であるため、上記のコードのコンパイル時には全く問題はそれほどあり、コンパイル時に問題はありませんが、、、ではありませんどのような引数の型、テイクので、内部を保持する場合、特定のリスト、我々が知らない、実行コールリストそれは、エラーの種類を変換することが可能であるときに報告されます。

上記の一般的なエラーは起こらなかっただろう場合。

public class Test {
    public static void main(String[] args){
        List<String> list = new ArrayList();
        list.add("1");
        list.add(1);//在编译期就会出错,因为用了泛型,虚拟机就会在编译期的时候检查泛型类型安全。
    }
}
复制代码

ジェネリックは、コンパイル時に存在しています。

たとえば。

public class Test {
    public static void main(String[] args) throws Exception{
        List<String> list = new ArrayList();
        list.add("hello");
        //list.add(23) //编译期会报错
        Class c = Class.forName("java.util.ArrayList");
        Method m = c.getMethod("add",Object.class);
        m.invoke(list,23);
        System.out.println(list); // [hello, 23]
    }
}
复制代码

上記のショーでは、コンパイルのジェネリック医薬品が唯一の効果的な、なぜそれがジェネリック医薬品がコンセプト、人気のポイントを消去するので、一般的な情報は、運用段階ではありませんであり、それは失敗して実行します。

ジェネリック医薬品の使用

3つの実用的な方法のジェネリックがあります。

ジェネリッククラス:public class Test<T>}{}Tは未知のタイプを表します

一般的なインターフェース:public interface Test<T>{}と定義されたクラスなど

一般的な方法:public <T> void Test(T name){}

ジェネリッククラスを使用します

ジェネリッククラスは、私たちはほとんどがArrayListに、HashMapの、HashSetのある使用するJavaで非常に重要な役割を持っています。

それはそうの中にあるものをコンテナのソースは確かではない、Javaのジェネリックを読み取るために表示されますので、あなたはあなたにそれを見てみたい場合は、これらのコンテナは、確かにこれまで以上にめまい、ジェネリックの私たち自身の定義完璧でしたクラスアウト。

//这个T可以换成随便一个字母 ,只不过我写泛型都用的T,你可以换成A,B,C...
public class Test<T> {
    T name;
    public Test(T name){
        this.name = name;
    }
    public T getName() {
        return name;
    }

    public void setName(T name) {
        this.name = name;
    }

复制代码
//如果不传泛型类型的话,那么默认的就是Object型什么都可以传
Test test = new Test("hello");
//传入的数据类型不为基本类型,否则编译期会报错,开头我解释过为什么会报错了
Test<Integer> test1 = new Test<>(418);
复制代码

汎用インタフェースを使用します

汎用インタフェースと類似したのジェネリッククラスの定義は、私たちの共通の汎用インタフェースは、リスト、地図、設定されています。

汎用インタフェースの私たち自身の定義のすべての古いルールの最初の。

public interface Test<T>{
    T getName(T name);
}
复制代码
//如果实现接口的时候不传入数据类型的话,需要将泛型声明也要写到类中要不然会报错
class Test1<T> implements Test<T>{

    @Override
    public T getName(T name) {
        return null;
    }
}

//实现接口的时候传入数据类型的话,就不用把泛型声明也写到类中了
class Test2 implements  Test<String>{

    @Override
    public String getName(String name) {
        return name;
    }
}
复制代码

一般的な方法を用いて、

一般的な方法を用いて、

public <T> void getName(T name){} 
public <T,K> void getNameAndValue(T name, K value){}
public <T,K,V> void getNameAndValueAndV(T name, K value, V v){}//总的来说就是参数需要多少泛型,返回值前面就得定义几个泛型要不然编译期会出错
复制代码

一般的なワイルドカード

なぜ使用はそれがワイルドカード?

クラスとJavaの内部の間の継承関係は、猫は動物を拡張するなど、あるその後、猫は動物のサブクラスですが、コレクションは、例えば、この概念を継承していない、List<Cat> catListList<Animals> animalListあなたはanimalListがcatListの親であると言うことはできません、見えにくいですうち2クラス間の接触、しかし、我々はそれを行う方法の唯一のサブカテゴリ動物が含まれるリストを作りたいですか?

  1. この方法の百、千、1万サブクラスは、あなたがそれをあまりにも時間がかかるをしないということであれば、この方法はまた、しかし、動物を達成することができますが、一つは、サブクラス定義のリスト動物の数の数であり、 。

  2. 第二は、達成するために、ワイルドカードを使用することです。例えば:List<? extends Animals> animalsこの時間は、動物は動物だけのサブクラスを追加し、リストを取得します。

ワイルドカードの基本的な考え方?

  1. ボーダレスワイルドカード:?たとえば、あなたは一般的な、未知のすべてのタイプを受け取ることができます

    public class Test {
       public static void main(String []args){
           List<Integer> list = new ArrayList<>();
           list.add(1);
           list.add(2);
           list.add(3);
           list.add(4);
           List<String> stringList = new ArrayList<>();
           stringList.add("h");
           stringList.add("e");
           stringList.add("l");
           stringList.add("l");
           stringList.add("o");
           getList(stringList);
           getList(list);
       }
        //无论传入什么List都会被接收
       public static List getList(List<?> list){
           return list;
       }
    复制代码

    使用リスト<?>あなたはタイプが何であるかを知っているが、それには(ヌル)list.addていないため、ヌルのすべての種類があるので、リストの方法クレームは、追加することはできません。例えば

    public static List getList(List<?> list){
        // list.add(1);//会报参数不匹配的错误,编译期报错
        // list.add("hello");//会报参数不匹配的错误,编译期报错
           list.add(null);//添加成功
           return list;
    }
    复制代码

    あなたはどのようなあなたのタイプのイエスを知らないので、オブジェクトは、getメソッドを受信するために使用することができます。

    public static List getList(List<?> list){
        int i = list.get(0); //编译期报错
        String j = list.get(1); //编译期报错
        Object o = list.get(3); //运行正确
        return list;
    }
    复制代码
  2. 境界ワイルドカード:<?Eが延び>のサブタイプは、一般的なEおよびEを受けることができるが、ああ、インターフェースであってもよい、例を見るだけでなく、Eクラスがあります。

    //这个是继承了类的用法
    public class Test {
        public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            getList(list);
            List<String> strings = new ArrayList<>();
            strings.add("hello");
            getList(strings);//编译期报错
        }
    
        public static List getList(List<? extends Number> list) {
            return list;
        }
    }
    
    
    复制代码
    public class Test {
        public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            list.add(1);
            getList(list);// 编译期报错
            List<Test2> test2s = new ArrayList<>();
            getList(test2s);
        }
        //上边界为接口的实现,只要是实现了此接口的类都可以被当做泛型传进来
        public static List getList(List<? extends Test1> list) {
            return list;
        }
    }
    
    interface Test1{
    
    }
    class Test2 implements Test1{}
    复制代码

    上記は、境界で見ることができます。<?Eは、拡張>あなたがEをサブクラスタイプに渡さなければならないことである、またはクラス実装インタフェースという。

  3. 境界ワイルドカードを下げて:<?スーパーE>例えば、Eの親クラスEとの種類する必要が渡されます

    public class Test {
        public static void main(String[] args) {
            List<Animals> animals = new ArrayList<>();
            getList(animals); 
            List<Cat> cats = new ArrayList<>();
            getList(cats);
            List<Dog> dogs = new ArrayList<>();
            getList(dogs);//编译出错,因为Dog不是Cat的父类
    
        }
    
        public static List getList(List<? super Cat> list) {
            return list;
        }
    }
    class Animals{}
    class Cat extends  Animals{}
    class Dog extends  Animals{}
    复制代码

終わり

私たちはほとんどが一般的なリスト、地図、両方のバーは、実際には、私たち自身のプログラミングは、ジェネリック医薬品の多目的利用をして、コードの特定の量を削減するだけでなく、より良いコードの外観を作ることができるで使用するJavaで考えますレイ6月の言葉は、他の人は私が詩のようなコードを書くと言う、私はあなたがJavaのああのように、はるかに行くことを願っています。

最後に、前に進むその後、ポイントのポイントのようなあなたの小さな手のトラブル、その後、この記事のように、親指を転送し、それぞれが私の文章力です。

千覚(JUE)公共の番号を見て、私はそれでメッセージ交換をバック与えます。

おすすめ

転載: juejin.im/post/5dfde5dc51882512327a64b2