今天敲代码的时候,想到创建一个set数组,结果不假思索的就写了下面这行代码
结果编译器报错:“不能创建泛型数组”
那么为什么不能创建泛型数组呢,如果想要使用该怎么办呢?😕
- 首先,java中我们不能实例化一个泛型数组,但是确实可以定义一个这样的变量
这是因为,泛型具有擦除机制,在运行时的类型会被擦除为了与之前版本类库的融合(不重写之前的类库),所以目前采用了类型擦除这种方法.
比如:
class Pair<T> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
擦除后
class Pair {
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
//当然擦除后的类型不一定是Object还有可能是它的最近的父类型
-
(Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。)
因此jvm只知道存储的是一个object类的对象,并且会在编译的时候也就是擦除之前判断操作的数据类型是否一致, -
类型检查就是针对引用的
其实下面的第二了例子算是上转型对象,还是属于父类对象,所以都可以接收.
ArrayList<String> arrayList1=new ArrayList();
arrayList1.add("1");//编译通过
arrayList1.add(1);//编译错误
String str1=arrayList1.get(0);//返回类型就是String
ArrayList arrayList2=new ArrayList<String>();
arrayList2.add("1");//编译通过
arrayList2.add(1);//编译通过
Object object=arrayList2.get(0);//返回类型就是Object
知道了这些,我们再来看看为什么不能创建泛型数组
由于泛型具有擦除机制,在运行时的类型参数会被擦除,Java只知道存储的对象是一个Object而已,而对于Java的数组来说,他必须知道它持有的所有对象的具体类型,而泛型的这种运行时擦除机制违反了数组安全检查的原则。
如果想使用泛型数组该这么办呢?
- 直接去掉实例化里的泛型
2. 或者直接使用List<List<Integer>>,用list代替数组,这种方式比较推荐不容易出错