例子:
public class A {
void get(Class<B> clazz) {
}
void call() {
get(B.class);
get(C.class); // error:C类不是B类, C只是B的子类
}
void getM(Class<? extends B> clazz) {
}
void callM() {
getM(B.class);
getM(C.class);
}
void list() {
List<B> rs = new ArrayList<B>();
rs.add(new B());
rs.add(new C()); //correct,因为C的实例可以认为是B类型的
rs.get(1); //return type is B
List<C> ss = new ArrayList<C>();
ss.add(new B()); //error: B的实例不可以认为是是C类型的
ss.add(new C());
rs = ss; //error: C类型的List不能转为B类型的List
List<? extends B> ms = new ArrayList<B>();
ms.add(new B()); //error: 因为有?号,代表未知类型,而不是B,也不是C
ms.add(new C()); //error: 同上
ms = ss;
rs = ms; //error: 未知类的List不能转为B类型的List
ms.get(0); //return type is B
}
<T> T[] makeArray(T t) {
T aa = new T();
return new T[100]; // error:因为类型变量在运行时不存在,也就没有办法在运行时检查数组的实际类型了
}
class B {}
class C extends B {}
}
看上在例子,总结出以下几点:
1在泛型的应用当中,也要注意类和对象的区别,比如上面C类是B类的子类,但是,C类并不是B类。而C的实例对象可以认为是B类型的;
2带有通配符?的集合不能加入元素;
3子类的集合不能转为父类型的集合;
4不存在运行的泛型类型变量,只有在编译时有。