一:为什么要有泛型

泛型的概念:

  1. 所谓泛型,就是允许定义在类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及类型参数。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的参数类型,也称为类型实参)。
  2. 从JDK 1.5以后,Java引入了“参数化类型”的概念,允许我们在创建集合时再指定集合元素的类型,正如:List,这表示该List只能保存字符串类型的对象。
  3. JDK 1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,从而可以在声明集合变量、创建集合对象时传入类型实参。

    二:在集合中使用泛型

    (1)创建集合对象,不使用泛型:

    好处:

    集合不使用泛型时,默认的类型就是Object类型,可以存储任意类型的数据。

    弊端:

    不安全,会引发异常。

    (2)创建集合对象,使用泛型:

    好处:

  4. 避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型。

  5. 把运行期异常(代码运行之后会抛出的异常),提升到了编译期(写代码的时候会报错)。

    弊端:

  6. 泛型是什么类型,便只能存储什么类型的数据。

    三:自定义泛型结构

    (1)泛型类:

    1. class MyGeneric<T> {
    2. T t;
    3. public void print(T t){
    4. System.out.println(t);
    5. }
    6. T show(T t){
    7. return t;
    8. }
    9. }
    10. //测试
    11. public class TextGeneric {
    12. public static void main(String[] args) {
    13. MyGeneric<String> myGeneric = new MyGeneric<>();
    14. String s = myGeneric.show("aaa");
    15. System.out.println(s);
    16. myGeneric.print(new String("hgk"));
    17. }
    18. }

    (2)泛型接口:

    第一种使用方式:

    定义接口的实现类,实现接口,指定接口的泛型。public interface 接口名

    第二种使用方式:

    接口使用什么泛型,实现类就使用什么泛型,类跟着接口走,就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型。

    (3)泛型方法:

    泛型定义在方法的修饰符和返回值类型之间。

    1. 修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){
    2. 方法体;
    3. }

    含有泛型的方法,在调用方法的时候确定泛型的数据类型。
    传递什么类型的参数,泛型就是什么类型。
    静态方法不建议创建对象使用,可以直接“类名.方法名”来使用。

    四:通配符的使用

    ?:代表任意的数据类型

    使用方式:

    1. 不能创建对象使用。
    2. 只能作为方法的参数使用。

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

      泛型的上限限定: ? extends E 代表使用的泛型只能是E类型的子类/本身。
      泛型的下限限定: ? extends E 代表使用的泛型只能是E类型的父类/本身。