Java泛型

泛型(generics)

前言

出现的缘由:想让一个类能够用于全部类型,可是咱们在之前定义的时候,只能定义一种类型,因而就出现了泛型。java

泛型使用

咱们能够看看 Java 定义的 List 接口的使用。dom

import java.util.ArrayList;
import java.util.List;

public class GenericTest {
    public static void main(String[] args) {
        // 指定类型 ,list 只能存储 String 元素,告诉 Java 这个 List 只能有 String 元素
        List<String> strList = new ArrayList<>();
        strList.add("str1");
        strList.add("str2");
        strList.add("str3");
        strList.forEach(System.out::println);
    }
}

上面的 List 的引用指向的是 ArrayList 对象,咱们看一下 ArrayList 中的 add 方法定义。code

看一下 ArrayList 的 add 方法对象

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

能够看到要添加的元素类型是 E,那么这个 E 来自哪里呢?咱们看一下 ArrayList 的定义:接口

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

咱们建立对象时是这样的:ci

List<String> strList = new ArrayList<>();

也就是说,这个 E 就是咱们在建立 ArrayList 对象时放入的类型,经过看 add 方法咱们发现,要添加的元素也必须是这个类型。element

固然别的类不必定是这样,要根据泛型的定义来判断使用的方式,具体状况,具体分析。rem

如何定义一个泛型

将类型定义在类后面的尖括号 ,能够定义多个。编译器

public class MyGenericType1<MyType1, MyType2> {
    private MyType1 type1;
    private MyType2 type2;   
}

其实泛型就是类型擦除,而后在调用的时候,帮咱们作强制类型转换。若是出现错误,报错信息会显示在调用的那一行it

协变和逆变

协变和逆变都是针对引用类型的,不能用于建立对象类型,在建立对象时必须指定一个明确类型。

协变
List<? extends Person> persons = null;

这种形式就是协变,使用协变时,类必须是 ? extends 后面的类自己或其子类。

逆变
List<? super Student> person2s = null;

这种形式就是逆变,使用逆变时,类必须是? super 后面的类自己或其父类。

import java.util.ArrayList;
import java.util.List;

public class GenericTest {
    public static void main(String[] args) {
        // 指定类型 ,list 只能存储 String 元素,告诉 Java 这个 List 只能有 String 元素
      //  协变:类必须是 ? extends 后面的类自己或其子类
        List<? extends Person> persons = null;
        // 不能够加入(List并无记住是什么类型,须要指定明确的类型)
//        persons.add(new Person());
//        persons.add(new Student());
        persons = new ArrayList<Person>();
        persons = new ArrayList<Student>();

        // 逆变:类必须是 ? super 后面的类自己或者其父类类
        List<? super Student> person2s = null;
        person2s = new ArrayList<Person>();
        person2s = new ArrayList<Student>();

    }
}

写入使用逆变,读取使用协变。能够参考 Java 类库中的方法。

泛型总结

泛型最重要的就是这两点。

  • 编译器检查并进行类型擦除。
  • 使用时会进行类型强制转换。
相关文章
相关标签/搜索