java泛型--擦除

1、什么是擦除

java的泛型是一种伪泛型,对于类型参数T,如果没有边界则擦除到Object,如果有边界则擦除到第一个边界。对于泛型类型则擦除为原生类型。
边界:对泛型的参数类型上设置限制条件,例如重用extends关键字将泛型参数类型限定为某个类的子类<T extends SuperClass>那么SuperClass为T的一个边界

体现类型擦除的例子

Class<T>被擦除为Class

 /* 一个利用反射产生数组的类 */
class ArrayMaker<T>{
	priavte Class<T> kind;
	public ArrayMaker(Class<T> kind){
		this.kind =kind;
	}
	T[] create(int size){
		//这里会有警告,因为Class<T>被擦除为Class,所以这个函数
		//并不能确定kind的具体类型
		return (T[]) Array.newInstance(kind,size);
	}
}

泛型参数T被擦除为HasF,即它的第一个边界

class HasF{
	public void f(){};
}
public class Test<T extends HasF>{
	private T obj;
	public Test(T x){ obj = x;}
	//若没有extends HasF则会报错,实际上T被擦除为HasF
	public void g(){ obj.f();}
	public static void main(String[] args){
		Test<HasF> t = new Test<>(new HasF());
	}
}
编译器保证类型的一致性

即如果泛型类Test<T,U>有两个泛型参数,虽然他们的类型信息都被擦除了,但是编译器可以识别T和U是不同的类型

2、什么时候进行擦除

擦除都发生在边界处。对于传给类型参数的值,在传进来时只是进行了编译期的检查;对于传递出去的值是在传递出去时加入了转型。这里的边界就是传进来和传出去时。

一个例子
//这个例子是,在Holder类中有一个私有域obj,类提供设置私有域和获取私有的方法set()和get()

//首先是使用Object替代泛型写法
public class SimplerHolder{
	private Object obj;
	public void set(Object obj) {this.obj=obj;}
	public Object get() {return obj;}
	public static void main(String[] args){
		SimpleHolder holder = new SimpleHolder();
		holder.set("Item");
		String s =(String) holder.get();//这里需要转型
	}
}
//然后是泛型的写法
public class GenericHolder<T>{
	private T obj;
	public void set(T obj) {this.obj=obj;}
	public T get() {return obj;}
	public static void main(String[] args){
		GenericHolder<String> holder = new GenericHolder<>();
		holder.set("Item");//传递进去的值
		String s = holder.get();//传递出来的值
	}
}

通过反编译上面两个类可以发现他们的字节码完全相同,即在使用set()方法时都是编译器执行类型检查,对于get()方法使用非泛型实现时是手动加了(String)进行转型,而使用泛型实现时是编译器帮你插入了(String)这个转型代码,两者并无区别。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值