chap8-泛型程序设计

本文详细介绍了Java中的泛型编程,包括泛型的基础概念、泛型类和方法的定义,以及类型擦除和桥方法。同时,讨论了泛型的限制,如不能用基本类型实例化类型参数,无法创建参数化类型的数组等。此外,还阐述了泛型类型的继承规则和通配符的使用,如子类型限定和超类型限定。最后,提到了泛型在实际编程中的注意事项,如类型安全性和多态性冲突的解决策略。
摘要由CSDN通过智能技术生成

chap8-泛型程序设计

泛型

泛型基础

  1. Java5中引入泛型;
  2. ArrayList<String>:<>表示类型参数
  3. 定义简单泛型类:
public class Pair<T>
{
    private T first;
    private T second;
    public Pair(){first = null; second = null;}
    ...
}
//多个泛型类型
public class Pair<T , U>
{
    ....
}
  1. 注意泛型方法定义,泛型方法可以在普通类中定义,也可以在泛型类中定义;
    //单一个方法既使用泛型的时候也使用可变参数,此时容易导致堆污染
    public static <T> T getMiddle(T... a)
    {
        return a[a.length / 2];
    }
String mid = ArrayAlg.<String>getMiddle("John" , "Q." , "Public");
  1. **当调用一个泛型方法时,可以把具体类型包围在尖括号中,放在方法名前面;**c++则是将具体类型放在方法名后面;
  2. 泛型类或方法可以对类型变量加以约束:<T extends Comparable>,<T extends bounding type>: T是其子类型,可以是接口或类;多个约束: <T extends Comparable & Serializable>
  3. Java继承中,可以根据需要拥有多个接口超类型,但最多有一个限定可以是类,如果有一个类作为限定,它必须是限定列表中的第一个限定;
  4. 虚拟机没有泛型类型对象,所有对象都属于普通类,无论何时定义一个泛型类型,都会自动提供一个相应的原始类型,这个原始类型的名字就是去掉类型参数后的泛型名称,类型变量会被擦除类型擦除,并替换为其限定类型;无限定的变量替换为Object;
  5. 原始类型用第一个限定来替换类型变量,如果没有给定限定 ,就替换为Object;
  6. 编写一个泛型方法调用时,如果擦除了返回类型,编译器会插入强制类型转换,当访问一个泛型字段时,也要插入强制类型转换;
  7. Java虚拟机的类型擦除会与多态产生冲突,解决方案是使用桥方法在Java虚拟机中,一个方法由返回类型和参数类型共同指定,编译器可以为2个仅返回类不同的方法生成字节码,虚拟机能够正确处理这种情况,但我们不允许编写仅返回类型不同的方法;
  8. Java泛型转换总结:
    • 虚拟机中没有泛型,只有普通类和方法(类型擦除);
    • 所有的类型参数都会替换为它们的限定类型;
    • 会合成桥方法来保持多态;
    • 为保证类型安全性,必要时会插入强制类型转换;

  1. Java泛型限制:

    • 不能用基本类型实例化类型参数(原因在于类型擦除,Object类型不能存储int, double,值)
    • 运行时类型查询只适用于原始类型,虚拟机中的对象总有一个特定的非泛型类型,所有的类型查询只产生原始类型;同理,getClass()方法总是返回原始类型;
    • 不能创建参数化类型的数组: Java不支持泛型类型的数组;
    var  table  =  new Pair<String>[10];		//ERROR!!!!
    //如果需要收集参数化类型对象,可以简单使用:   ArrayList<Pair<String>>
    
    • 不能实例化类型变量:
    public Pair(){ first  = new T() ;  second = new T();}		//ERROR!!
    
    • 不能构造泛型数组
    • 泛型类的静态上下文中类型变量无效,不能在静态字段或方法中引用类型变量,静止使用带有类型变量的静态字段和方法;
    • 不能抛出或捕获泛型类的实例,即不能抛出,也不能捕获泛型类的对象,泛型类扩展Throwable都是不合法的,catch字句中不能使用类型变量;
    • 可以利用泛型取消Java的检查型异常检查
    • 注意泛型类型擦除后产生的冲突:倘若两个接口类型是同一接口的不同参数化,一个类或类型变量就不能同时作为这两个接口类型的子类

泛型类型的继承规则

  1. 无论ST有什么关系,Pair<S> , Pair<T>都没有任何关系;
  2. 泛型类可以扩展或实现其他的泛型类;

通配符类型

  1. 在通配符中,子类型限定通配符允许类型参数发生变化:Pair< ? extends Employee>:限定泛型只能为T类型的子类或本身;
//可以将Pair<Manager> , Pair<Employee>传递给该方法参数  , 
//Pair<Manager>  是Pair<? extends Employee>的子类型
public  static  void  printBuddies(Pair<? extends Employee> p)
  1. 超类型限定:<? super T> : 限定泛型只能为T类型的父类或本身,可以为方法提供参数,但不能使用返回值
  2. 带有超类型限定的通配符允许你写入一个泛型对象,而带有子类型限定的通配符允许你读取一个泛型对象;
  3. Java无限定通配符:类型不确定时使用:<?>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值