通过实例比较泛型通配符(T E与?)的用法
static class Point<T>{ private T x; public Point (T x){ this.x=x; } public void setX(T x){ this.x=x; } public T getX(){ return this.x; } } /** * wild capture在通配符被绑定为新值的时候会警告 * 因此通配符可防止数据修改,保证数据安全 */ public static void fun(Point<?> a){ // a.setX("AA"); // 编译错误 提示“capture of ?” System.out.println(a.getX()); } /** * 泛型的意义: * 0.待定数据类型提高API灵活性(flexible) * 1.使用时指定类型省略了Object类型转换(cast),保证类型安全 * 2.通过多个继承限制实现类型限制(bound) * 3.结合通配符保证数据安全 * 类型参数:类型待定(由使用者决定)的参数的类型占位符 * 泛型方法声明方式:【方法修饰符后设置类型参数符号T,形参处使用类型参数符号T】 * 使用时按照【PECS - producer extends consumer super】 */ public static <T extends Father> void testGeneric(List<? super T> fathers, T person) { /** * 实例化时必须指定类型 */ List<? super T> lowList1 = new ArrayList<T>(); // List<? super T> list1 = new ArrayList<?>(); // 编译出错 lowList1.add(person); // lowList1.add(new Father("father")); // 编译出错 // list1.add(new Child("00")); // 编译出错,泛型不可传递? /** * 内部变量(类的成员变量或方法的局部变量)仅可使用已声明的泛型或通配符泛型 */ List<T> tmpList = new ArrayList<T>(); // List<E> tmpList2 = new ArrayList<T>(); // 编译出错,E是未知类型 /** * 可变类型提供灵活性,结合通配符还能保证数据安全 */ Point<String> a= new Point<>("A"); fun(a); Point<Integer> b= new Point<>(10); fun(b); /** * 通配泛型因其通配区间内类型无法确定,故通配区间内的方法不可用 * 上界通配,通配区间为[upLimit, allSubClasses] 有上限无下限 不可添加元素,可用上界及以上层次的方法 */ ArrayList<? extends Father> uplist = new ArrayList<Father>(); // uplist.add(new Object());// 编译出错 // uplist.add(new Father("father"));// 编译出错 // uplist.add(new Child("child"));// 编译出错 if (uplist.size() > 0) { Father father = uplist.get(0); father.say(); GrandFather grandFather = uplist.get(1); grandFather.say(); uplist.forEach(var -> var.say()); } /** * 下界通配,通配区间为[allParentClasses, lowLimit] 有下限无上限 可添加子类对象元素,仅可用Object公共方法 */ ArrayList<? super Child> lowList = new ArrayList<Father>(); lowList.add(new Child("child")); lowList.add(new GrandChild("grandChild")); // lowList.add(new Father("father")); // 编译出错 Object obj = lowList.get(0); // Father fatherObj = lowList.get(0);// 编译出错 /** * 以Number类举例下界限定通配 */ List<? super Number> data = new ArrayList<>(); data.add(10); data.add(new BigDecimal(1000)); data.add(10.07f); data.forEach(var ->var.toString()); // data.add(new Object()); //编译报错 }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

浙公网安备 33010602011771号