//下面两个会报错,因为泛型参数是要创建对象时确定 public static T a; public static T test1(T t) { }
//这里不报错,因为这是一个泛型方法,此T非彼T test2(T t)的T public static <T> T test2(T t) { return t; }
泛型类型中的方法冲突
因为擦除后两个equals方法变成一样的了
1 2 3 4 5 6 7 8 9 10
//方法冲突,因为擦除后变一样了 @Override public boolean equals(T obj) { return super.equals(obj); }
@Override public boolean equals(Object obj) { return super.equals(obj); }
没法创建泛型实例
因为类型不确定
1 2 3 4 5 6 7 8 9 10 11 12
class Test02 { //无法创建一个类型参数的实例。下面会报错 public static <E> void append(List<E> list) { // E elem = new E(); // compile-time error // list.add(elem); } //通过反射创建一个参数化类型的实例 public static <E> void append(List<E> list, Class<E> cls) throws Exception { E elem = cls.newInstance(); // OK list.add(elem); } }
没有泛型数组
因为数组是协变,擦除后就没法满足数组协变的原则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// Plate<Apple>[] applePlates = new Plate<Apple>[10];//不允许 // T[] arr = new T[10];//不允许 Apple[] apples = new Apple[10]; Fruit[] fruits = new Fruit[10]; System.out.println(apples.getClass()); //class [Lcom.zero.genericsdemo02.demo02.Apple; System.out.println(fruits.getClass()); //class [Lcom.zero.genericsdemo02.demo02.Fruit; fruits = apples; // fruits里面原本是放什么类型的? Fruit or Apple // Apple[] fruits[0] = new Banana();//编译通过,运行报ArrayStoreException //Fruit是Apple的父类,Fruit[]是Apple[]的父类,这就是数组的协变 //如果加入泛型后,由于擦除机制,运行时将无法知道数组的类型 Plate<?>[] plates = new Plate<?>[10];//这是可以的