泛型类、泛型接口

泛型类和接口在jdk中是大量使用的,这里以List接口为例:
image.png
image.png
由于List接口是一个泛型接口,那么其下的toArray方法中的T的类型必须和List的类型一模一样,我们只需要在实例化List时指定T到底是哪个类型即可。其中的T只能是一个类,不可以使用基本数据类型来填充,但可以使用其包装类代替。如:
image.png

注意事项

  • 一个泛型类或接口可以指定多个泛型参数,如: ```java public class Student{

}

  1. - 泛型类的构造器写法:“pulic Student(){ }”,而不是“pulic Student<E, T, P>(){ }”
  2. - 泛型不同的引用不能相互赋值,如:List<String>和List<Integer>时无法相互赋值
  3. - 泛型如果不知道具体类型,泛型对应的类型均按Object处理
  4. - 异常类时不可以是泛型的
  5. - 在接口/类上声明了泛型,该类中的静态方法是不可以使用这个泛型的,原因是:类的泛型是在类实例化的时候指定的,但是类中的静态方法确实在类实例化化之前就被编译了
  6. - 创建泛型数组时,不能使用“E[] arr=new E[size]”,但是可以使用“E[] arr=(E[])new Object[size]”
  7. - 泛型类是可以被其它类继承的,通常有以下四种情况:
  8. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12564419/1618494905732-4d7dd769-d01e-4252-aa0e-d0c216e92377.png#height=408&id=czAvL&margin=%5Bobject%20Object%5D&name=image.png&originHeight=816&originWidth=1760&originalType=binary&ratio=1&size=623944&status=done&style=none&width=880)<br />其中第四中相当于“class Child extends Father<Object , Object>”
  9. - 如果AB的父类,G<A>不是G<B>的父类,但A<G>是B<G>的父类
  10. <a name="Jaiwc"></a>
  11. # 泛型方法
  12. 方法也可以被泛型化,简称为泛型方法,泛型方法可以存在泛型类,也可以存在非泛型类,并且存在泛型类时,泛型方法中的泛型和类中的泛型没有任何关系。泛型方法定义的结构通常是:<br />“[访问权限] <T> 返回类型 方法名(参数,也可以是泛型指定) 抛出的异常”,如:
  13. ```java
  14. public class Student {
  15. public <E> List<E> fromArrToList(E[] arr) {
  16. List<E> list = new ArrayList<>();
  17. Collections.addAll(list, arr);
  18. return list;
  19. }
  20. public static void main(String[] args) {
  21. Student student = new Student();
  22. String[] stringArr = new String[]{"aaa", "bbb", "ccc"};
  23. List<String> list = student.fromArrToList(stringArr);
  24. System.out.println(list);
  25. }
  26. }

image.png
注意:泛型类和接口中的泛型是不能被静态方法使用的,但是这里的泛型方法确是可以指定为泛型的,原因是:泛型方法的泛型是在被调用的时候确定的,不管是实例调用还是静态调用都没有区别,因此静态调用并不影响泛型方法中泛型的指定,所以Java允许泛型方法是静态的。如:

public class Student {

    public static  <E> List<E> fromArrToList(E[] arr) {
        List<E> list = new ArrayList<>();
        Collections.addAll(list, arr);
        return list;
    }

    public static void main(String[] args) {
        Student student = new Student();
        String[] stringArr = new String[]{"aaa", "bbb", "ccc"};
        List<String> list = Student.fromArrToList(stringArr);
        System.out.println(list);
    }

}

泛型类中的类型参数与泛型方法中的类型参数是没有相应的联系的,泛型方法始终以自己定义的类型参数为准。为了避免混淆,如果在一个泛型类中存在泛型方法,那么两者的类型参数最好不要同名,如:

public class Test1<T>{

    public  void testMethod(T t){
        System.out.println(t.getClass().getName());
    }
    public  <E> E testMethod1(E e){
        return e;
    }
}