java泛型出现原因分析

时间:2020-12-24 19:24:54

为了较少潜在的关于擦除的混淆,你必须清楚地认识到这不是一个语言特性。特使Java的泛型实现中的一种折中,因为泛型不是Java语言出现时就有的组成部分,所以这种折中是必须的。这种折中会使你痛苦,因为你需要习惯并了解为什么他会这样。

如果泛型在Java1.0中就已经是其中的一部分了,那么这个特性就不会使用擦除来实现--他将使用具体化,使类型参数保持为第一类实体,因为你就能够在类型参数上执行基于类型的语言操作和反射操作。你将在本章稍后看到,擦除减少了泛型的泛化性。泛型在Java中仍旧是有用的只是不如他们本来设想的那么没用,二原因就是擦除。

在基于擦除的实现中,泛型类型被当做第二类类型处理,即不能再某些重要的上下文环境中使用的类型。泛型类型只有在静态类型检查期间才出现,在此之后,程序中的所有泛型类型都将被擦除,替换为他们的非泛型上界。例如,诸如List<T>这样的类型注解将被擦除为List,而普通的类型变量在未指定边界的情况下将被擦除为Object.

擦除的核心动机是使得泛化的客户端可以用非泛化的类库来使用,反之亦然,这经常被称为“迁移兼容性”。在理想情况下,当所有的事物都可以同时被泛化时,我们就可以专注于此。

在现实中,即使程序员只编写泛型代码,他们也必须处理在Java SE5之前编写的非泛型类库。那些类库的作者可能从没有想过要泛化他们的代码,或者可能刚刚开始接触泛型。

因为Java泛型不仅必须支持向后兼容性,即现有的代码和类文件仍旧合法,并且继续保持其之前的含义;而且还要支持迁移兼容性,使得类库按照他们自己的步调变为泛型的,并且当某个类库变为泛型时,不会破坏依赖于他的代码和应用程序。在决定这就是目标之后,Java设计者们和从事此问题相关工作的各个团队决策认为擦除是唯一可行的解决方案。通过允许非泛型代码与泛型代码共存,擦除使得这种向着泛型的迁移称为可能。

例如,假设某个应用程序具有两个类库X和Y,并且Y还要使用类库Z。随着Java SE5的出现,这个应用程序和这些类库的创建者最终可能希望迁移到泛型上。但是,当进行这种迁移时,他们有着不同的动机和限制。为了实现迁移兼容性,每个类库和应用程序都必须与其他所有的部分是否使用了泛型无关。这样,他们必须不具备探测其他类库是否使用了泛型的能力。因此,某个特定的类库使用了泛型这样的证据必须被擦除。

如果没有某种类型的迁移途径,所有已经构建了很长时间的类库就需要与希望迁移到Java泛型的开发者说再见了。但是,类库是编程语言无可争议的一部分,他们对生产效率会产生最重要的影响。因此这不是一种可以接受的代价。擦除是否是最佳的或者唯一的迁移途径,还需要时间证明。