java基础之泛型

泛型类

public class Pair<T,U> {

    private T first;
    ....
}

上面的T被成为类型变量

泛型字母类型
E 集合的元素类型.
K,V 表的关键字与值的类型
T,U,S 任意类型

泛型类可看作普通类的工厂

泛型方法

class ArrayAlg
{
    public static <T> T getMiddle(T... a) 
    {
        return a[a.length/2];
    }
}

调用泛型方法时,如何传给泛型方法具体类型

String middle = ArrayAlg.<String>getMiddle("John")

当然可以直接写成如下,编译可以根据传入的参数类型推断出来,而有的编译器可能会报错

String middle = ArrayAlg.getMiddle("John")

类型变量的限定

class ArrayAlg
{
    public static <T> T getMiddle(T... a) 
    {
        ....
    }
}

因为类型变量可以是任何类,我们可以对该类型做一些限定

public static <T extends Comparable> T getMiddle(T... a)

还可以多重限定

public static <T extends Comparable&Serializable> T getMiddle(T... a)

类型变量 擦除

何来擦除
虚拟机是没有泛型类型对象的。

擦除后,用什么来替换泛型
泛型类型都会被原始类型所代替,如果有类

public class Interval<T extends Comparable&Serializable>

有限定类型,那么T被替换为Comparable(原始类型用第一个限定的类型变量来替换)。如果是无限定类型变量T,那么就直接替换为Object。

虚拟机如何处理泛型表达式
原代码:

Pair<Employee> buddies = ...;
Employee buddy = buddies.getFirst();

既然到了虚拟机那里,所有的Employee泛型都变成Object了,getFirst()方法返回的也是Object,那要泛型何用?
其实虚拟机是这样做的:

Pair buddies = ...;
Employee buddy = (Employee)buddies.getFirst();

也就是代码中的泛型最终通过强转类型实现。

兼容泛型出现前的遗留代码所带来的隐性问题
泛型出现前ArrayList无需增加泛型修饰,这带来问题是,虽然18行是由泛型String限制,但是进入方法setList后,10行给list添加了整数1,编译器是检查不到的,只会给出警告
这里写图片描述
24行读取该list,仍旧不会有问题,直到运行中将整数强转为String 出现异常。
这里写图片描述
警告中给出的建议是:
* 泛型限定
* 确认不会有问题后,利用@SuppressWarnings ‘unchecked’

运行时的类型
擦除后

Pair<Employee> employeePair;

在虚拟机里和Pair无异了

Pair<String> stringPair = ...
Pair<Employee> employeePair = ...
if(stringPair.getClass() == employeePair.getClass()) //是相同的。

不能创建参数化类型的数组
什么叫 参数化类型的数组呢?不懂,
这里写图片描述
如下

Pair<String>[] table = new Pair<String>[10];
Object[] objarray = table;
objarray[0] = new Pair<Employee>();//因为类型变量被擦除,编译器不会报错,但这会导致运行中错误。

这种问题是编译器无法检测到的错误是需要力图避免,因为他也是可以被避免的,使用下面来替换数组形式。

ArrayList<Pair<String>> table = ...;
table.add(new Pair<Employee>()); //会编译时报错的。

数组会记住它的元素类型,如下

String[] ss = new String[10];
Object[] os = ss;
os[0] = new Integer(); //会报错 

Varargs警告
这里写图片描述

T.. ts

参数中出现的这个其实是一个数组,那么如果这个T是个带泛型的对象呢?
比如

Pair<Sring>

那么虚拟机就需要为其创立一个带泛型数组,这违背了上面的规矩,但java格外开恩,只需要加@SafeVarargs或@SuppressWarnings ‘unchecked’就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值