为什么在java中不能创建泛型数组

本文探讨Java泛型擦除机制及其影响。介绍为何在Java中无法创建泛型数组,并通过示例展示如何理解泛型擦除导致的信息丢失。解释泛型擦除背后的动机及代价。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前段时间在上国外某教授的algorithm课程,提到在java中不能创建泛型数组,课后也有这个思考题,自己百思不得其解,于是翻开了《think in java》这本书,在书的第15章,写到。这是由于擦除机制。(尽管通读了第15章,小白作者还是有很多地方不明白,如果读者能明白,望不吝赐教)

public class ErasedTypeEquicalence {
    public static void main (Sring args[]){
        Class c1=new Arraylist().getClass();
        Class c2=new Arraylist().getClass();
    System.out.println(c1==c2);
    }
    
    /*ourput:
    *true
    */
}

在这个小代码中我们看到结果也许有有点迷糊,为什么返回的true,其实arraylist<String>和arraylist<Integer>很容易被认为是不同的类型,不同的类型在行为方面肯定不同。然而上面的程序认为他们是相同的类型。

在下面,书上又介绍了另一端比较长的例子。

//: generics/LostInformation.java
import java.util.*;

class Frob {}
class Fnorkle {}
class Quark {}
class Particle {}

public class LostInformation {
  public static void main(String[] args) {
    List list = new ArrayList();
    Map map = new HashMap();
    Quark quark = new Quark();
    Particle p = new Particle();
    System.out.println(Arrays.toString(
      list.getClass().getTypeParameters()));
    System.out.println(Arrays.toString(
      map.getClass().getTypeParameters()));
    System.out.println(Arrays.toString(
      quark.getClass().getTypeParameters()));
    System.out.println(Arrays.toString(
      p.getClass().getTypeParameters()));
  }
} /* Output:
[E]
[K, V]
[Q]
[POSITION, MOMENTUM]
*///:~

Class.getTypeParemeters() 将 "返回一个TypeVarivable的对象数组表示有泛型声明所声明的类型参数",好像暗示我们可能发现参数类型的信息,但是从输出我们可以看到,能够发现的只是用作参数占位符的标识符,这,并没有什么卵用。

书上提到了:这是一个残酷的现实:在泛型代码内部,无法获得任何有关泛型参数类型的信息。

泛型是通过擦除实现的,这意味着当你使用泛型时,任何具体的类型信息都被擦除了,你唯一所知道的就是你在使用一个对象。之前说的arraylist<String>和arraylist<Integer>在运行时会被擦除成“原生”的类型,即list。

书上提到了 泛型不是java语言出现就有的组成成分,所以为了减少擦除的混淆,我们要意识到,擦除是java语言实现泛型的一种折中,这种折中会让我们痛苦。。由于擦除的存在,泛型在java中的使用不像它原来设想的那么有用,尽管还是存在用处。

擦除的核心动机是它使得泛化的客户端可以用非泛化的类库,反之亦然,这经常被称为“迁移兼容性”。

擦除的代价是显著的,泛型不能用于显式地引用运行时类型的操作之中,例如转型、instanceof操作和new表达式。因为所有关于参数的类型信息都已经丢失了。

因此像  public class Eraesd<T>{

....

T [] arrary =new T[size]     ;//这样的代码会出现error  (won't compile)

...

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值