泛型类的约束与局限性

来源:互联网 发布:nginx 允许指定目录 编辑:程序博客网 时间:2024/05/21 17:06

下面阐述一下Java 泛型类的使用时,需要考虑的一些限制,大多数限制都是类型擦除引起的。

1.不能用基本类型实例化 类型参数

类型擦除后,类型变量被替换为限定类型(假设可以为基本类型,则被替换为Object),显然Object不能存储基本类型。

2.运行时类型查询只适用于原始类型

不解释

3.不能创建参数化类型 的数组

对于

Pair<String> []table =new Pair<>[10];//Error

类型擦除后 数组会记住元素的类型 Pair 
如果试图向数组中添加其他类型的对象,则会抛出ArrayStoreException异常
而对于同是Pair类型的对象

Pair<Scanner> p = new Pair<>();
虽然能通过数组存储检测,但是在使用他时仍然会导致一个类型错误,出于这个原因 最好不要建立参数化类型的数组
注:虽然不能创建,但是可以声明

4.varargs警告

不是很懂,简单理解:

向一个参数数目可变的方法

public static <T>void addAll(Collection<T>coll,T...ts){}
ts实际上就是一个泛型数组 
相当于 addAll(Collection<T>coll,T[]ts)
为了调用这个方法,Java虚拟机 就会创建一个Pai<Stirng>数组,这就违背了前面的规则,不过对于这种情况,规则有所放松,只会得到一个警告


5.抑制(suppress)警告

方法前可以加两种注释

@SuppressWarnings("unchecked")

@SafeVarargs

6.不能实例化类型变量

T.class 在类型擦除后可能变为Object.class.同样的 new T()   这种 表达式本身就是不合法的.

Java SE 8之后,要想得到实例最好的解决方法是让调用者提供一个构造器表达式 String:new

7、不能创建泛型数组

比如说

public static <T extends Comparable>  Pair<T> makePair(T[ ] a ){

T[]mm =new T[2];

  }


类型擦除后,mm构造的永远就是Comparable元素的数组。避免这种情况,最好的例子就是ArrayList:

封装一个Object[]类型的数组

不过,当返回类型带有类型变量时,

public static <T extends Comparable>  Pair<T> makePair(T[ ] a ){

Object[]mm =new Object[2];

..

return (T[])mm;

  }

当把Object[]的引用赋给Compaable[]变量时就会抛出ClassCastException

就需要让调用者提过一个数组构造器表达式

8.泛型类静态上下文中类型变量无效

静态部分属于整个类,而类型变量需要构建对象时实例化,与静态部分矛盾

9.不能抛出捕获泛型类实例,可以使用类型变量 


原创粉丝点击