java核心之泛型(三)约束

——每天的寥寥几笔,坚持下去,将会是一份沉甸甸的积累。


从前一篇文章我们可以看出擦除机制的强大,由于擦除,使得新的语法糖——泛型被成功的加入到java语法中,同时又兼容了java虚拟机原有的处理机制。

不过,擦除的加入也带来了不少的约束与限制。

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

比如说Pair<double>是不被允许的,因为类型擦除过后,Pair含有Object类型的域,而Object不能存储基本数据类型double。


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

因为泛型类型会被擦除,最后不是我们想要的结果。比如

if(a isinstanceof Pair<String>)//ERROR
由于擦除,结果只会变成判断是否是Pair的实例,而不是我们原来想要的判断是否是Pair<String>的实例

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

Pair<String> [] table = new Pair<String>[10];//ERROR
擦除过后,table的类型为Pair[],然后
Object[] array = table;
array[0] = "hello";//ERROR-component type is Pair,throw arrayStoreException
array[0] = new Pair<Employee>();//pass the array store check but still result in a type error
如果需要收集参数化类型对象,直接使用ArrayList:ArrayList<Pair<String>>最安全且有效


4.Varargs警告

从3可以看出java不支持泛型类型的数组,然后对应一个类似的——可变参的方法,如addAll(T...ts),往里面传泛型类型的参数实例就会垂涎Varargs警告。


5.不能实例化泛型类型

new T(...),new T[...],T.class这些的表达式都不能使用,因为T会被擦除为Object
那样的话结果会始终new出来Object类型的实例,这不是我们想要的。必要时需要用反射来实现

public static <T> Pair<T> makePair(Class<T> c1){
    return new Pair(c1.newInstance(), c1.newInstance());
}
那么既然new T()不被允许,我们又该怎么new一个对象出来呢?答案是用Object类型。

看ArrayList的实现

public class ArrayList<E>{
	Object[] element;
	public E get(int n){
		return (E)element[n];
	}
	public void set(int n,E e){
		element[n] = e;
	}
}

这里需要注意的是,如果返回的不是E类型,而是E[]类型,那么就出问题,像下面

public static <T> T[] minmax(T...a){
	Object[] mm = new Object[2];
	return (T[])mm;//编译通过,运行时类型转换异常
}

上面这种情况还是得需要反射来解决
public static <T> T[] minmax(T...a){
	T[] mm == (T[])Array.newInstance(a.getClass().getComponentType(),2);
	return mm;//编译通过,运行时类型转换异常
}


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

public class A<T>{
	private static T a;//error
	public static T get(){}//error,因为擦除,而且类A没有被实例化
}

7.类型擦除后的冲突

publicclass Pair<T>{
	public boolean equals(T value){}//由于擦除,变成equals(Object),这会和从Object父类继承过来的equals(Object)同名冲突
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值