1700447005
1700447006
List<String>ls=new ArrayList<String>();
1700447007
1700447008
List<Integer>li=new ArrayList<Integer>();
1700447009
1700447010
System.out.println(li.getClass()==li.getClass());
1700447011
1700447012
}
1700447013
1700447014
以上代码将返回为true,原因很简单,List<String>和List<Integer>擦除后的类型都是List,没有任何区别。
1700447015
1700447016
(2)泛型数组初始化时不能声明泛型类型
1700447017
1700447018
如下代码编译时通不过:
1700447019
1700447020
List<String>[]listArray=new List<String>[];
1700447021
1700447022
原因很简单,可以声明一个带有泛型参数的数组,但是不能初始化该数组,因为执行了类型擦除操作,List<Object>[]与List<String>[]就是同一回事了,编译器拒绝如此声明。
1700447023
1700447024
(3)instanceof不允许存在泛型参数
1700447025
1700447026
以下代码不能通过编译,原因一样,泛型类型被擦除了:
1700447027
1700447028
List<String>list=new ArrayList<String>();
1700447029
1700447030
System.out.println(list instanceof List<String>);
1700447031
1700447032
1700447033
1700447034
1700447036
编写高质量代码:改善Java程序的151个建议 建议94:不能初始化泛型参数和数组
1700447037
1700447038
泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码:
1700447039
1700447040
class Foo<T>{
1700447041
1700447042
private T t=new T();
1700447043
1700447044
private T[]tArray=new T[5];
1700447045
1700447046
private List<T>list=new ArrayList<T>();
1700447047
1700447048
}
1700447049
1700447050
这段代码有什么问题呢?t、tArray、list都是类变量,都是通过new声明了一个类型,看起来非常相似啊!但这段代码是编译通不过的,因为编译器在编译时需要获得T类型,但泛型在编译期类型已经被擦除了,所以new T()和new T[5]都会报错(可能有读者疑惑了:泛型类型可以擦除为顶级类Object,那T类型擦除成Object不就可以编译了吗?这样也不行,泛型只是Java语言的一部分,Java语言毕竟是一个强类型、编译型的安全语言,要确保运行期的稳定性和安全性就必须要求在编译器上严格检查)。可为什么new ArrayList<T>()却不会报错呢?
1700447051
1700447052
这是因为ArrayList表面是泛型,其实已经在编译期转型为Object了,我们来看一下ArrayList的源代码就清楚了,代码如下:
1700447053
1700447054
public class ArrayList<E>extends AbstractList<E>
[
上一页 ]
[ :1.700447005e+09 ]
[
下一页 ]