public class wildcard {
/**
* 下列显示一个static方法,该方法计算一个Shape数组的总面积(假设Shape是含有area方法的类);
* 而Circle和Square 则是继承Shape类),假设我们想要重写这个计算总面积的方法,使得该方法能够
* 使用Collection<Shape>这样的参数,Collection是集合,能够存储一些项,而这些项可以用一个
* 增强的for循环来处理,由于是增强的for循环,因此代码是相同的,如果传递一个Collection<Shape>
* 那么程序将正常运行,,可是要传递一个Collection<Square> 会发生什么情况?,答案依赖于
* 是否Collection<Square> IS-A Collection<Shape> 既 是否具有协变性
* Java数组是具有协变性的,于是Square[] IS-A Shape[] ,一方面这种一致性意味着,如果数组是
* 协变,那么集合也将是斜边的,数组的协变性导致代码得以编译,但此后会产生一个运行时异常,
* (ArrayStoreException)使用泛型的全部原因就在于产生编译错误而不是类型不匹配的运行时异常
* 所以泛型集合不是协变的,,因此我们不能将Collection<Square> 以 Collection<Shape>形式传过去
*
*/
// public static double totalArea(Shape[] arr){
// double total = 0;
// for(Shape s : arr){
// if(s != null){
// total += s.area();
// }
// }
// return total;
// }
// public static double totalArea(Collection<Shape> arr){
// double total = 0;
// for(Shape s : arr){
// if(s!=null)
// total+=s.area();
// }
// return total;
// }//totalArea 方法,如果传递一个Collection<Square> 则方法不能运行
/**
* 现在问题是,泛型(以及泛型集合)不是协变的(但是有意义),而数组是协变的
* 若无附加的语法,则用户就会避免使用集合(Collection),因为失去协变性将使得代码失去灵活性
* Java 5 通配符来弥补这个不足,通配符用来表示参数类型的子类(或超类) 下列代码是带有限制的
* 通配符的使用,下边将Collection<T>作为参数的方法totalArea,其中T IS-A Shape 因此Collection
* <Square> 和 Collection<Shape>都是可以接受的参数,,通配符还可以不带限制使用(此时假设为)
* extends Object 或者不用extends 而用super(来表示超类而不是子类)
*/
// public static double totalArea(Collection<? extends Shape> arr){
// double total=0;
// for(Shape s:arr){
// if(s!= null)
// {
// total+=s.area();
// }
// }
// return total;
// }
//用通配符修正后的totalArea方法,如果传递一个Collection<Square>,则方法能够正常运行
}
Java带有限制的通配符
最新推荐文章于 2023-04-05 23:16:09 发布