Java泛型

目录

定义简单泛型类

类型变量和类型参数

Pair

ArrayAlg

泛型代码和虚拟机

类型擦除(erasure)

泛型转换

泛型的限制与局限性

泛型类型继承规则

通配符类型(wildcard type)


泛型程序设计意味着编写的代码可以对不同类型的对象进行重用

定义简单泛型类

类型变量和类型参数

//<T><U><S> 类型变量  
ArrayList<String> files = new ArrayList<>();

E:集合的元素类型

K和V:键和值的类型

T、U、S:任意类型

Pair
public class Pair<T>
{
    private T first;
    private T second;
​
    public Pair()
    {
        first = null;
        second = null;
    }
    
    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }
}
​
//或
public class Pair<T,U>
{
    T first;
    U second;
​
    public Pair(T first, U second) {
        this.first = first;
        this.second = second;
    }
}

ArrayAlg

public class ArrayAlg
{
    /**
     * 从一组T类型的数据中获取最大值和最小值
     * @param t T类型的数组
     * @return Pair<T>  返回一对最大值和最小值。如果t为null或为空,则返回null
     * <T extends Comparable> 是对T类型的一个限定,限制T只能是实现了Comparable的类。如果不设置限定,则写为<T>
     */
    public static <T extends Comparable> Pair<T> minmax(T[] t)
    {
        if(t == null || t.length == 0) return null;
​
        T min,max;
        min = max = t[0];
​
        for (int i = 0; i < t.length; i++) {
            if (t[i].compareTo(min) < 0)
                min = t[i];
            if (t[i].compareTo(max) > 0)
                max = t[i];
        }
​
        return new Pair<>(min ,max);
    }
    
    /**
     * 泛型方法,返回泛型重载参数的中间那个参数
     * <T>是声明,T是返回值 重载参数本质上是参数数组
     */
    public static <T> T middle(T... args)
    {
        return args[args.length/2];
    }
}

泛型代码和虚拟机

类型擦除(erasure)

定义泛型类型时,编译器会提供一个原始类型(raw type),名字就是去掉类型参数后的泛型类型名。

类型变量会被擦除(erased),并被替换为限定类型,或对于无限定的,则替换为Object。

泛型转换

  1. 虚拟机中没有泛型,只有普通类和方法

  2. 所有参数类型都会替换为它们的限定类型

  3. 会合成桥方法保持多态

  4. 为保持类型安全性,必要时会插入强制类型转换

泛型的限制与局限性

  • 不能用基本类型去实例化

    Pair<double>;   //Error
    Pair<Double>;   //Correct
  • 运行时类型查询只适用于原始类型(即泛型类)

  • 不能创建参数化类型数组

    Pair<String> str = new Pair<>[10];  //Error
  • Varargs警告(可变参数警告)

  • 不能直接实例化类型变量

    public Pair() { first = new T(); second = new T();}//Error 
  • 不能构造泛型数组

    类型擦出机制总会使构造方法构造限定类型数组或Object数组

  • 不能在静态字段和方法中定义和引用类型变量

  • 不能抛出或捕获泛型类的实例

  • 可以取消对检查型异常的检查

泛型类型继承规则

无论T与S有什么关系,genericity<T>与genericity<S>都没有任何关系。想要在泛型程序中利用继承关系,则须引入通配符类型

通配符类型(wildcard type)

public static boolean hasNulls(Pair<?> pair){}  //使用了无限定通配符?,不需要标注泛型方法
public class Employee{}
public class Manager extends Employee {}
​
//这里?没法改为T
public static void printBuddies(Pair<? extends Employee> pair){}    //pair有2种类型选择:Employee or Manager
​
//超类型限定
public static void minmaxBonus(Manager[] managers, Pair<? super Manager> pair)  //pair有3种类型选择:Object、Employee or Manager
//?不是类型变量
public static void swapHelper(Pair<?> pair)
    {
        ? t = pair.getFirst();   //ERROR
        pair.setFirst(pair.getSecond());
        pair.setSecond(t);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值