Java基础_泛型

J1.泛型方法

泛型方法的规定

  1. 泛型方法可以放在普通类内也可以放在泛型类内
  2. 基本格式为
    public static <T> T name(){}
    类型变量:就是<T>,他放在修饰符的后面(public static)
    T为返回值类型,他放在类型变量后面
    name就是该泛型方法的名字了!
  3. 调用泛型方法时可以不填类型变量,JAVA可以自动根据形参推断(但最好填上)

基本泛型方法

以下代码实现找到一个数组内中间的那一个元素(下面包含对对应元素的解释)

  1. 解释:定义了一个静态的,接收一可变长数组且返回T类型数值的函数
  2. T… a 表示一个可变长的数组,所以a就是一个数组!
  3. return 一个T类型的数据,这里取数组
    public static <T> T getMiddle(T... a){
        return a[a.length/2];
    }

调用该泛型方法(假定该泛型方法放在一名为 Tmethod的普通类中)

String middle = Tmethod.<String>getMiddle("hello","world","nood","python");
System.out.println(middle);

// 返回nood

类型变量的限定

代码实现找到数组中最小值,方法就是逐个比较
因为我们需要在比较中使用compareTo方法,但该方法仅限于继承了comparable接口的类使用所以我们为类型变量进行限定:
<T extends Comparable>
将调用者传入的类型限制为继承了comparable接口的类(限定的可以是类或者接口)

    public static <T extends Comparable> T min(T[] a) {
        if (a == null || a.length == 0) return null;
        T smallest = a[0];
        for(int i=0;i<a.length;i++){
            if(smallest.compareTo(a[i])>0) smallest=a[i];
        }
        return smallest;
    }

一个类型变量可以使用多个限定,多个限定之间使用 & 隔开,如
<T extends xxx & xxx>



J2.泛型代码和虚拟机

类型擦除

  • JAVA泛型不同于C++的泛型,可以把JAVA泛型视为“使用了泛型擦除的伪泛型”
  • 如下方代码,我们继承了comparable接口,该接口就作为上界,而类型变量T相当于下界
  • 当我们使用Pair<String>时,确定了下界为String,而上界就是comparable,JAVA在处理时,会把下界擦除并转而使用上界,这就是所谓的泛型擦除(也就是说,我们实际上使用的是Pair<Comparable>)
  • 上界也叫作原始类型
Pair<T extends Comparable>

Pair<String>

注意!当我们继承多个限定类型后,原始类型就被确定为第一个限定类型,所以以下代码经过类型擦除后,原始类型使用的是Serializable而不是Comparable

Pair<T extends Serializable & Comparable>

翻译泛型

首先定义泛型类Pair,以下所有翻译泛型解释都基于该类

class Pair<T> {
    private final T first;
    private final T second;

    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public T getSecond() {
        return second;
    }
}

翻译泛型表达式
代码中我们使用类Pair,并且指定其类型参数为String

  1. 规定,如果不写方法的返回值类型,那么编译器插入强制类型转换
  2. 解析:原本p.getFirst()理应写成p.<String>getFirst(),来表示其返回一个字符串类型,但我们这里略去不写,JAVA就会按照类型擦除原则返回一个Object类型的值,然后立即进行强制类型转换,把他变回String类型的值,最后完成赋值操作
Pair<String> p = new Pair<>("hey","not");
String s = p.getFirst();

翻译泛型方法


泛型转换的四个事实

  • 虚拟机中没有泛型,只有普通的类和方法
  • 所有的类型参数都用他们的限定类型替换
  • 桥方法被合成来保持多态
  • 为了保持类型的安全性,必要时插入强制类型转换


J3.约束和局限性

不能使用基本类型实例化类型参数
简言之,就是不可以用double来实例化类型参数,但是可以使用Double!
当包装器类型不接受替换时,可以使用独立的方法或者类处理他们


运行时查询只适合原始类型
不要试图使用instanceof来检测泛型类型,如下代码所示必定返回一个错误

Pair<String> p;
if(p instanceof Pair<String>)

泛型强制类型转换会导致警告

Pair<String> s = (Pair<String>) p;

对一个泛型对象使用getClass()返回原始类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhillery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值