让 Foo.class 是 Class<Foo> 类型有什么好处?通过类型推理的魔力,可以提高使用反射的代码的类型安全。另外,还不需要将 Foo.class.newInstance() 强制类型转换为 Foo。比如有一个方法,它从数据库检索一组对象,并返回 JavaBeans 对象的一个集合。您通过反射来实例化和初始化创建的对象,但是这并不意味着类型安全必须完全被抛至脑后。例如下面这个方法:
public <T> T getInstant(Class<T> t) throws IllegalAccessException, InstantiationException {
T r = t.newInstance();
return r;
}
可以防止类型重载
在泛型不是协变中提到,在使用 List< Number> 的地方不能传递 List< Integer>,那么有没有办法能让他两兼容使用呢?答案是:有,可以使用通配符。
主要是 extends 和 super 关键字。比如:
HashMap< T extends String>;
HashMap< ? extends String>;
HashMap< T super String>;
HashMap< ? super String>;
类型的上界是 T,参数化类型可能是 T 或 T 的子类:
public class Test {
static class Food {}
static class Fruit extends Food {}
static class Apple extends Fruit {}
public static void main(String[] args) throws IOException {
List<? extends Fruit> fruits = new ArrayList<>();
fruits.add(new Food()); // compile error
fruits.add(new Fruit()); // compile error
fruits.add(new Apple()); // compile error
fruits = new ArrayList<Fruit>(); // compile success
fruits = new ArrayList<Apple>(); // compile success
fruits = new ArrayList<Food>(); // compile error
fruits = new ArrayList<? extends Fruit>(); // compile error: 通配符类型无法实例化
Fruit object = fruits.get(0); // compile success
}
}
? extends
的数据结构里写入任何的值。但是,由于编译器知道它总是Fruit的子类型,因此我们总可以从中读取出Fruit对象:
Fruit fruit = fruits.get(0);
表示类型的下界是 T,参数化类型可以是 T 或 T 的超类:
public class Test {
static class Food {}
static class Fruit extends Food {}
static class Apple extends Fruit {}
public static void main(String[] args) throws IOException {
List<? super Fruit> fruits = new ArrayList<>();
fruits.add(new Food()); // compile error
fruits.add(new Fruit()); // compile success
fruits.add(new Apple()); // compile success
fruits = new ArrayList<Fruit>(); // compile success
fruits = new ArrayList<Apple>(); // compile error
fruits = new ArrayList<Food>(); // compile success
fruits = new ArrayList<? super Fruit>(); // compile error: 通配符类型无法实例化
Fruit object = fruits.get(0); // compile error
}
}
编译器在不知道这个超类具体是什么类,只能返回Object对象,因为Object是任何Java类的最终祖先类。
Object fruit = apples.get(0);
从上述两方面的分析,总结PECS原则如下:
PECS JDK源码案例Collections copy方法
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。