泛型笔记

一、概念

泛型提供了编译时类型安全监测机制,该机制允许我们在编译时检测到非法的类型数据结构。本质上就是参数化类型,也就是所操作的数据类型被指定为一个参数。

优点:类型安全、消除了强制类型的转换、一定程度上的代码复用。

泛型类型不能够用继承来理解

二、泛型类

常用的泛型标识:T、E、K、V (K V一般作为键值对结合使用)

  1. 泛型类在创建对象的时候,指定操作的具体数据类型。

  2. 如果泛型类在创建对象的时候没有指定类型,将按照Object类型来操作。

  3. 泛型类不支持基本数据类型。

  4. 同一泛型类,根据不同的数据类型创建的对象,本质上是同一类型(this.class)。

  5. 带有类中泛型类型的方法,不可被声明为static

三、泛型类派生子类

子类也是泛型类,子类和父类的泛型类型要一致。即使子类泛型类型有扩展,也要保证有一个类型和父类一致

class ChildGeneric<T> extends Generic<T>

子类不是泛型类,继承时父类要明确泛型的数据类型

class ChildGeneric extends Generic<String>

四、泛型接口

实现类不是泛型类,接口要明确数据类型

public class Apple implements Generator<String>

实现类也是泛型类,实现类和接口的泛型类型要一致。即使子类泛型类型有扩展,也要保证有一个类型和接口类一致

public class Pair<T,E> implements Generator<T>

五、泛型方法

泛型类,是在实例化类的时候指明泛型的具体类型

泛型方法,是在调用方法的时候指明泛型的具体类型,泛型方法中的泛型类型与类中的泛型类型相互独立

  1. public与方法返回值中间的泛型列表<T>非常重要,可以理解为声明此方法为泛型方法。

  2. 只有声明了泛型列表的方法才是泛型方法,泛型类中使用了泛型的成员方法并不是泛型方法。

  3. 泛型列表<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。

  4. 与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。

public <T,E,...> 返回值类型 方法名(形参列表){
方法体...
}

泛型方法可变参数

可以传入多个相同类型的参数

public <E> void print(E... e){
for (E e1 : e){
System.out.println(e);
}
}

六、类型通配符

类型通配符一般是使用 “ ? ”代替具体的类型实参

所以,类型通配符是类型实参,而不是类型形参

public void test(Box<?> box){}

类型通配符的上限

/接口<? extends 实参类型>

要求该泛型的类型,只能是实参类型,或实参类型的子类类型

类型通配符的下限

/接口<? super 实参类型>

要求该泛型的类型,只能是实参类型或实参类型的父类类型。此种方式的形参方法,不保证约束要求;参数要用Object类型去接收

七、类型擦除

泛型是java1.5版本引进的概念,但是,泛型代码能够很好地和之前版本的代码兼容。那是因为,泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,我们称之为——类型擦除。

 

 

 

 

 

 

 

 

八、泛型数组

可以声明带泛型的数组引用,但是不能直接创建带泛型的数组对象。

泛型在编译期会做类型擦除,而数组会在整个编译器一直持有类型,会产生冲突

public class generic {
   public static void main(String[] args) {
       List<String>[] list1 = new ArrayList<String>[5];    //×
       List<String>[] list2 = new ArrayList[5];            //√
  }
}

可以通过java.lang.reflect.Array的new Instance(Class<T>,int)创建 T[] 数组

Array.newInstance(class,length)

尽量不要采用泛型数组,而是采用泛型集合代替泛型数组

 

posted @ 2021-09-19 16:15  你们都不上班吗  阅读(47)  评论(0)    收藏  举报