Java教程

泛型

本文主要是介绍泛型,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

泛型

一、泛型概述

  • 泛型是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型;
  • 泛型也可以看成是一个变量,用来接收数据类型;
    • E e:Element 元素
    • T t:Type 类型

二、泛型的定义与使用

2.1 定义和使用含有泛型的类

定义格式:

修饰符 class 类名<泛型>{}

例如:

public class GenericClass<E> {

    private E name;

    public GenericClass() {
    }

    public GenericClass(E name) {
        this.name = name;
    }

    public E getName() {
        return name;
    }

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

}

使用泛型:在创建对象的时候确定泛型

public class Demo01 {
    public static void main(String[] args) {
        GenericClass<String> genericClass = new GenericClass<>();
        genericClass.setName("创建对象即确定泛型");
        String name = genericClass.getName();
    }
}

2.2 含有泛型的方法

定义格式:

修饰符 <泛型> 返回值类型 方法名(参数){}

例如:

public class GenericMethod {

    //定义一个含有泛型的方法
    public <M> void method01(M m) {
        System.out.println(m);
    }

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

使用格式:调用方法时,确定泛型的类型

public class Demo02 {

    public static void main(String[] args) {
        GenericMethod gm = new GenericMethod();
        gm.method01("字符串");
        gm.method01(123);
        gm.method01(false);

        GenericMethod.method02("静态方法");
        GenericMethod.method02(111);
    }
}

2.3 含有泛型的接口

定义格式:

修饰符 interface 接口名<泛型>{}

例如:

public interface GenericInterface<I> {
    public abstract void method(I i);
}

使用格式:

2.3.1 定义类时确定泛型的类型

例如:

public class GennericInterfaceImpl1 implements GenericInterface<String> {
    @Override
    public void method(String s) {
        System.out.println(s);
    }
}
2.3.2 创建对象时确定泛型的类型(常用)

例如:

/**
 * 含有泛型的接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型。
 * 就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型
 */
public class GennericInterfaceImpl2<I> implements GenericInterface<I> {
    @Override
    public void method(I i) {
        System.out.println(i);
    }
}
public class Demo03 {
    public static void main(String[] args) {
        GennericInterfaceImpl1 impl1 = new GennericInterfaceImpl1();
        impl1.method("字符串");

        GennericInterfaceImpl2<Integer> impl2 = new GennericInterfaceImpl2<>();
        impl2.method(100);

        GennericInterfaceImpl2<String> impl3 = new GennericInterfaceImpl2<>();
        impl3.method("创建对象时确定泛型类型");
    }
}

三、泛型通配符(?)

3.1 通配符基本使用

泛型的通配符:不知道什么类型来接收的时候,此时可以使用?,?表示未知通配符。

例如:泛型没有继承概念

/**
 * 泛型的通配符:
 *      ?:代表任意的数据类型
 * 使用方式:
 *      不能创建对象使用
 *      只能作为方法的参数使用
 */
public class Demo04Generic {

    public static void main(String[] args) {
        ArrayList<Integer> list01 = new ArrayList<>();
        list01.add(10);
        list01.add(20);

        ArrayList<String> list02 = new ArrayList<>();
        list02.add("a");
        list02.add("b");

        printArray(list01);
        printArray(list02);

    }

    /*
        定义一个方法,能遍历所有类型的ArrayList集合
        此时我们不知道ArrayList集合使用什么数据类型,就可以使用泛型的通配符<?>来接收数据类型
        注意:
            泛型没有继承概念(即方法入参不能用ArrayList<Object>来接收)
     */
    public static void printArray(ArrayList<?> arrayList){
        for (Object i : arrayList) {
            System.out.println(i);
        }
    }
}

3.2 通配符高级使用——受限泛型

之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置,但是在JAVA的泛型中可以指定一个泛型的上限和下限。

3.2.1 泛型的上限
  • 格式:类型名称<? extends 类名> 对象名称
  • 意义:只能接收该类型及其子类
3.2.2 泛型的下限
  • 格式:类型名称<? super 类名> 对象名称
  • 意义:只能接收该类型及其父类

比如:现已知Object类,String类,Number类,Integer类,其中Number是Integer的父类

public class Demo05Generic {

    public static void main(String[] args) {
        Collection<Integer> list1 = new ArrayList<>();
        Collection<String> list2 = new ArrayList<>();
        Collection<Number> list3 = new ArrayList<>();
        Collection<Object> list4 = new ArrayList<>();

        getElement1(list1);
        getElement1(list2);//报错
        getElement1(list3);
        getElement1(list4);//报错

        getElement2(list1);//报错
        getElement2(list2);//报错
        getElement2(list3);
        getElement2(list4);
    }

    // 泛型的上限:此时的泛型?,必须是Number类型或其子类
    public static void getElement1(Collection<? extends Number> coll){}

    // 泛型的下限:此时的泛型?,必须是Number类型或其父类
    public static void getElement2(Collection<? super Number> coll){}

}
这篇关于泛型的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!