Java擦除的问题

擦除的主要的正当理由是从非泛化代码到泛化代码的转变过程,以及在不破坏现有类库的情况下,将泛型融入到Java语言。擦除使得现有的非泛型客户端代码能够在不改变的情况下继续使用,直至客户端准备好用泛型重写这些代码。这是一个崇高的动机,因为他不会突然间破坏现有所有的代码。

擦除的代价是显著的。泛型不能用于显式地引用运行时类型的操作之中,例如转型,instanceof操作和new表达式。因为所有关于参数的类型信息都丢失了,无论何时,当你在编写泛型代码时,必须时刻提醒自己,你只是看起来好像拥有有关参数的类型信息而已。因此,如果你编写了下面这样的代码段:

Class  Foo<T>{
T var;
}

那么看起来当你在创建Foo的实例时:

Foo<Cat> f=new Foo<Cat>();

Class Foo中的代码应该知道现在工作于Cat之上,而泛型语法也在强烈暗示:在整个类中的各个地方,类型T都在被替换。但是事实并非如此,无论何时,当你在编写这个类的代码时,必须提醒自己:“不,他只是个Object”

另外,擦除和迁移兼容性意味着,使用泛型并不是强制的,尽管你可能希望这样:

public class GenericBase<T>{
	private T element;
	public void set(T arg){
		arg=element;
	}
	public T get(){
		return element;
	}
}
public class Derived1<T> extends GenericBase<T>{

}
public class Derived2 extends GenericBase{
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		Derived2 d2=new Derived2();
		Object obj=d2.get();
		d2.set(obj);
	}
}

Derived2继承自GenericBase,但是没有任何泛型参数,而编译器不会发出任何警告。警告在set()被调用时候才会出现。

为了关闭警告,Java提供了一个注解,我们可以在列表中看到它(这个注解在JavaSE5之前的版本中不支持);@SuppressWarnings("unchecked")

注意,这个注解被放置在可以产生这类警告的方法之上,而不是整个类上。当你要关闭警告时,最好是尽可能的“聚焦”,这样就不会因为过于宽泛的关闭警告,而导致意外地遮蔽掉真正的问题。

当你希望将类型参数不要仅仅当做Object处理时,就需要付出额外的努力来管理边界。并且与在C++,Ada和Eiffel这样的语言中获得参数化类型相比,你需要付出多得多的努力来获得少的少的回报。这就是说,对于大多数的编程问题而言,这些语言通常都会比Java更得心应手,这就是说,他们的参数化类型机制比Java的更灵活,更强大。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值