Java ジェネリックの概要、ジェネリック クラスの定義と使用、ジェネリック メソッドの定義と使用、ジェネリック インターフェイスの定義と使用、ジェネリック ワイルドカード?、制限付きジェネリック

ジェネリック医薬品の概要:

コレクションに格納されるデータのタイプはジェネリックと呼ばれます。ジェネリックは不明なデータ型です。使用するデータ型がわからない場合はジェネリックを使用できます。

オブジェクトを作成するときに、データ型を指定してジェネリック型に割り当てます。ジェネリック型は、データを格納するための変数とみなすこともできます。

一般的なジェネリック型: 文字 E は要素を表し、文字 T はタイプを表します。もちろん、ジェネリック型のデータ型がわかっている場合は、String などの特定のデータ型を渡すことができます。実際に文字列を E に渡します

import java.util.ArrayList;//导包
import java.util.Iterator;
public class Generic{
    
    
    public static void main(String[] args){
    
    
        // 1.集合中为了安全,一般是需要指定数据类型的,<类型>,类型值除int(Integer)、char(Character),其它类型将数据类型的首字母大写即可
        ArrayList<String> arraylist = new ArrayList<String>();
        arraylist.add("星期一");
        System.out.println(arraylist); // [星期一]
        arraylist.add("星期二");
        System.out.println(arraylist); // [星期一, 星期二]

        // 2.使用泛型的好处:避免数据类型转换,存什么类型取什么类型;将运行期异常提升到了编译器;泛型的弊端:指明数据类型后只能存储指定类型的数据。
        ArrayList<Integer> arrayInt = new ArrayList<Integer>();
        arrayInt.add(10);
        System.out.println(arrayInt);
        // arrayInt.add("20"); // 泛型是什么类型,在新增数据的时候就是什么数据类型的数据,否则编译不通过
        arrayInt.add(20);
        System.out.println(arrayInt);

        // 3.集合不使用泛型时,默认数据类型是Object,可以存储任意类型的数据,此时不安全会发生异常。
        ArrayList list = new ArrayList();
        list.add('1');
        list.add("abc");
        list.add(12);
        System.out.println(list); // 编译时提示: Generic.java使用了未经检查或不安全的操作; 打印结果:[1, 1, abc]

        // 4.使用迭代器遍历list:
        // 获取集合的迭代器:
        Iterator iter = list.iterator();
        //遍历并打印数据:
        //hasNext判断是否有元素
        while (iter.hasNext()) {
    
    
            // next获取元素
            Object item = iter.next();
            System.out.println(item);

            // 向下转型时会抛出异常:Exception in thread "main" java.lang.ClassCastException: java.base/java.lang.Integer cannot be cast to java.base/java.lang.String at Generic.main(Generic.java:37),使用泛型约束后在编译时就会提示
            String str = (String) item;
            System.out.println(str.length());
            System.out.println(str);
        }
    };
};

ジェネリックスを含むクラスを定義して使用します。

ジェネリック クラスを定義する場合は、クラス名の後に <type> を追加するだけで、クラス内のデータ型が山かっこ内の型に置き換えられます。ジェネリック クラスを使用する場合は、クラス名の後に <type> を追加するだけで済みます。違いは、ジェネリックスを使用してオブジェクトを作成できること、またはジェネリックスを使用せずにオブジェクトを作成できることですが、ジェネリックスを使用せずにオブジェクトを作成すると、デフォルトで Object 型になり、E の使用の場合と同様にお勧めできません。下:

汎用クラス:

// 定义含有泛型的类时,在类名称后面写<类型>即可,E表示任意元素的泛型
public class GenericClass<E> {
    
    
//public class GenericClass{
    
    
    // 1.定义一个含有泛型的类(模拟ArrayList集合),泛型是一个未知的数据类型,当不确定数据类型的时候可以使用泛型,泛型可以接收任意数据类型,在创建对象时在指明数据类型:
    private E name;
//    private String name;

    public E getName() {
    
    
//    public String getName() {
    
    
        return name;
    }

    public void setName(E name) {
    
    
//    public void setName(String name) {
    
    
        this.name = name;
    }
};

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

public class UserGenerIcClass {
    
    
    public static void main(String[] args) {
    
    
        // 1.使用GenericClass类,不传泛型时默认是Object类型
        GenericClass gc = new GenericClass();
        // 当创建类的时候,如果数据类型是写死的,那么在这里设置和读取的时候也只能是指定写死的类型,如:
        gc.setName("苦海");
        System.out.println(gc.getName());// 苦海

        // 2.使用泛型创建对象:
        GenericClass<Integer> gcInt = new GenericClass<Integer>();
        // gcInt.setName('1'); 使用了泛型,如果数据类型不符合就会编译不通过
        gcInt.setName(18);
        System.out.println(gcInt.getName());// 18

        GenericClass<Character> gcChar = new GenericClass<Character>();
        gcChar.setName('f');
        System.out.println(gcChar.getName());// f
    }
}

ジェネリックスを含むメソッドを定義して使用します。

ジェネリックスを使用してメソッドを定義します。

// 含有泛型的方法:泛型定义在方法修饰符和返回值之间,如: public <泛型> 返回值类型(参数(使用泛型)){}
public class DefGenericMethodsClass {
    
    
    // 前面定义了泛型,后面括号中才可以使用:这里S是随便写的,这里可以写任意字符串
    public <S> void defGenericMethods(S s) {
    
    
        System.out.println(s);
    }

    // 定义一个含有泛型的静态方法:
    public static <S> void staGenericMethods(S s) {
    
    
        System.out.println(s);
    }

    // 定义一个普通的方法:
    public static void commonMethods (String s) {
    
    
        System.out.println(s);
    }
}


一般的な方法を使用します。

public class UseGenericMethodsClass {
    
    
    public static void main(String[] args) {
    
    
        // 创建含有泛型方法的对象:
        DefGenericMethodsClass gm = new DefGenericMethodsClass();
        // 调用含有泛型的方法,传递什么类型,泛型就是什么类型
        gm.defGenericMethods(10); // 10
        gm.defGenericMethods('a'); // a
        gm.defGenericMethods("121"); // 121

        // 调用静态方法:
        DefGenericMethodsClass.staGenericMethods("静态方法");
        // 调用普通方法:接收参数时必须指定类型,且传参数时也要求一直
        gm.commonMethods("hello");
        // gm.commonMethods(true); // 定义什么类型,传递什么类型,否则报错
        // gm.commonMethods(123);
    }
}

ジェネリックスを備えたインターフェイスを定義して使用します。

ジェネリックスを使用してインターフェイスを定義します。

// 定义含有泛型的接口:在接口名称后面加<类型>
public interface DefGenericInterface<S> {
    
    
    // 定义一个抽象方法:
    public abstract void methods(S s);
}

ジェネリックスでインターフェイスを使用するには、次の 2 つの方法があります。

メソッド 1 インターフェイス実装クラス:

// 使用含有泛型的接口第一种方式:定义接口实现类,实现接口,指定接口泛型:
public class UseGenericInterface implements DefGenericInterface<String> {
    
    
    @Override
    public void methods(String s) {
    
    
        System.out.println(s);
    };
}

方法 1 では、インターフェイス実装クラスを使用します。

// 定义一个普通的类使用接口实现类:
public class UseGenericInterfaceClass {
    
    
    public static void main(String[] args) {
    
    
        UseGenericInterface gi = new UseGenericInterface();
        gi.methods("hello"); // hello
    }
}

モード 2 インターフェイス実装クラス:

// 使用含有泛型的接口第二种方式:接口使用什么泛型,实现类就用什么泛型,类跟着接口走,相当于定义了一个含有泛型的类,创建对象时指定泛型的类型
public class UseGenericInterfaceTwo<S> implements DefGenericInterface<S> {
    
    
    @Override
    public void methods(S s) {
    
    
        System.out.println(s);
    };
}

方法 2 では、インターフェイス実装クラスを使用します。

public class UseGenericInterfaceClassTwo {
    
    
    public static void main(String[] args) {
    
    
        UseGenericInterfaceTwo<Integer> gi = new UseGenericInterfaceTwo<Integer>();
        gi.methods(255); // 255
    }
}

一般的なワイルドカード?:

ジェネリック クラスまたはインターフェイスを使用する場合、渡されるデータのジェネリック型は不確実であり、ワイルドカード <?> で表すことができます。ただし、汎用ワイルドカードを使用すると、Objet クラスの共通メソッドのみが使用可能になり、コレクション内の要素のメソッドは使用できなくなり、データの受信のみが可能になり、コレクションにデータを保存できなくなります。

import java.util.ArrayList;
import java.util.Iterator;

// 泛型通配符:只能作为方法的参数使用,不能创建对象使用,如下面定一个万能遍历结合的方法
public class GenericWildcard {
    
    
    public static void main(String[] args) {
    
    
        ArrayList<Integer> list1 = new ArrayList<Integer>();
        list1.add(1);
        list1.add(2);
        forEachArrayList(list1);

        ArrayList<Character> list2 = new ArrayList<Character>();
        list2.add('z');
        list2.add('a');
        forEachArrayList(list2);
    }
    public static void forEachArrayList(ArrayList<?> list) {
    
    
        // 获取遍历器:
        Iterator<?> item = list.iterator();
        while(item.hasNext()){
    
    
            Object it = item.next();
            System.out.println(it);
        }
    }
}

制限されたジェネリック医薬品:

以前のジェネリックスを設定する場合は、クラスであれば制限なく設定できますが、Java ジェネリックスではジェネリックの上限と下限を指定できます。

一般的な上限: このタイプとそのサブクラスのみを受け入れることができます

形式: 型名 <? extends class> オブジェクト名

一般的な下限: このクラスとその親クラスのみ受信可能

形式: 型名 <? スーパークラス> オブジェクト名

import java.util.ArrayList;
import java.util.Collection;

public class GenericLimit {
    
    
    public static void main(String[] args) {
    
    
        // 定义多个类型的集合并测试受限泛型:
        Collection<Integer> list1 = new ArrayList<Integer>();
        getElementExtends(list1);
        // getElementSuper(list1); // 报错:只能传入当前类型或父类

        Collection<String> list2 = new ArrayList<String>();
        // getElementExtends(list2); // 报错:String和Number没有上下级关系
        // getElementSuper(list2); // 报错:String和Number没有上下级关系

        Collection<Number> list3 = new ArrayList<Number>();
        getElementExtends(list3);
        getElementSuper(list3);

        Collection<Object> list4 = new ArrayList<Object>();
        getElementExtends(list3);
        getElementSuper(list3);
    }
    // 类之间的继承关系:
    // Integer 继承-> Number 继承-> Object
    // String 继承-> Object

    // 定义一个泛型下限:传入的类型只能是Number或子类
    public static void getElementExtends(Collection<? extends Number> param){
    
    };
    // 定义一个泛型上限:传入的类只能是Number或父类
    public static void getElementSuper(Collection<? super Number> param){
    
    };
}

ヒント: この記事の写真やその他の資料はインターネットから取得したものです。侵害がある場合は、メールボックス [email protected] に電子メールを送信し、作者に連絡して削除してください。
作者:苦海

おすすめ

転載: blog.csdn.net/weixin_46758988/article/details/128088586