为什么说Java是伪泛型?
程序员文章站
2022-06-24 19:32:30
因为Java的泛型只在编译期起作用,就是在我们写代码时,起到一个检查的作用,当代码跑起来时,其内部并没有泛型。下面一个简单的例子就可以证明这一点。通过反射,我们可以不受约束地将一个任意类型的元素添加到一个有泛型的集合中,如下:// 这个方法可以给穿进来的泛型集合添加任意类型的元素 public void add(List al,Object obj) throws Exception { Class cls= al.getClass();...
因为Java的泛型只在编译期起作用,就是在我们写代码时,起到一个检查的作用,当代码跑起来时,其内部并没有泛型。下面一个简单的例子就可以证明这一点。
通过反射,我们可以不受约束地将一个任意类型的元素添加到一个有泛型的集合中,如下:
// 这个方法可以给传进来的泛型集合添加任意类型的元素
public <T> void add(List<T> al,Object obj) throws Exception {
Class cls= al.getClass();
Method m=cls.getMethod("add",Object.class);
m.setAccessible(true);
m.invoke(al,obj);
}
// 下面调用上述方法来给一个泛型集合添加任意类型元素
public void test1() throws Exception {
ReflectDemo rd=new ReflectDemo();
ArrayList<String> a=new ArrayList();
//正常情况下,是不能给一个<String>泛型的集合加入非String型元素的
rd.add(a,true);//add()方法就是上面写的方法
rd.add(a,23);
rd.add(a,new Car());//Car是自己写的一个类
System.out.println(a);
}
// 打印结果
[true, 23, Car(id=null, brand=null, color=null)]
通过这个例子可以看到,Java在运行时泛型并不起作用,通过反射拿到ArrayList的add方法,是没有泛型的,其参数类型为Object。所以可以添加别的类型的元素。
另一个更简单的例子也可以说明:
public void test1plus(){
ArrayList<String> a=new ArrayList<String>();
ArrayList b=new ArrayList();
System.out.println(a.getClass()==b.getClass());
}
运行后打印结果为true,可见虽然集合加了泛型,但其字节码与没加泛型的是同一个,所以泛型只存在于编译期。
本文地址:https://blog.csdn.net/L_beaman/article/details/109624556