import java.util.List;
import java.util.ArrayList;
interface Canine {}
class Dog implements Canine {}
public class Collie extends Dog {
public static void main(String[] args){
List<Dog> d = new ArrayList<Dog>();
List<Collie> c = new ArrayList<Collie>();
d.add(new Collie());
c.add(new Collie());
do1(d); do1(c);
do2(d); do2(c);
}
static void do1(List<? extends Dog> d2){
d2.add(new Collie());
System.out.print(d2.size());
}
static void do2(List<? super Collie> c2){
c2.add(new Collie());
System.out.print(c2.size());
}
}
该问题的答案表明,当方法采用通配符通用类型时,可以访问或修改集合,但不能同时访问或修改集合。(凯西和伯特)
这是什么意思?“ 当方法采用通配符通用类型时,可以访问或修改集合,但不能同时访问两者 ”?
据我所知,方法do1具有List<? extends Dog> d2
d2只能访问但不能修改。d2的方法List<? super Collie> c2
使c2可以被访问和修改,并且没有编译错误。
通用准则
该问题的答案表明,当方法采用通配符通用类型时,可以访问或修改集合,但不能同时访问或修改集合。(凯西和伯特)
这是一个很合理的第一近似值,但并不完全正确。更正确的是:
您只能将null添加到,Collection<? extends Dog>
因为其add方法采用的参数? extends Dog
。每当调用方法时,都必须传递声明的参数类型的子类型的参数。但是对于参数类型? extends Dog
,如果表达式为则编译器只能确保参数为兼容类型null
。但是,您当然可以通过调用clear()
或来修改集合remove(Object)
。
另一方面,如果您从a读取Collection<? super Dog>
,则其迭代器具有return type ? super Dog
。也就是说,它将返回对象的某个未知超类型的子类型的对象Dog
。但是不同的是,Collection可以Collection<Object>
仅包含的实例String
。因此
for (Dog d : collection) { ... } // does not compile
因此,我们唯一知道的是返回了Object的实例,即,迭代此类Collection的唯一类型正确的方法是
for (Object o : collection) { ... }
但是可以从一个集合中读取内容,而您只是不知道将得到什么类型的对象。
我们可以轻松地将该观察结果概括为:
class G<T> { ... }
和
G<? extends Something> g;
我们只能将null传递给声明类型的方法参数T
,但是我们可以调用返回类型的方法T
,并为结果分配一个type变量Something
。
另一方面,对于
G<? super Something> g;
我们可以将任何类型的表达式传递Something
给具有声明类型的方法参数T
,并且可以调用具有返回类型的方法T
,但只能将结果赋给类型变量Object
。
总之,使用通配符类型的限制仅取决于方法声明的形式,而不取决于方法的用途。
问题内容: 我试图了解下限和上限通配符的行为。 尝试编译以下代码时遇到问题。 为了弄清楚问题,我还尝试了下限通配符。幸运的是或不幸的是,代码可以很好地编译,但是却造成了很多混乱。 有人可以解释一下这两个代码段如何工作。如果有人可以提供其他示例/链接,那就太好了。 如果我在上面做错了什么,请纠正我。 提前致谢。 问题答案: 表示“未知类型”。 表示某种对象的集合。此“某种类型”可以是作为其子类或自身
我很困惑,如果下面的方法是相同的?有什么细微的区别吗? 非常感谢你的建议。 方法1 方法二
这个问题的答案表明,当方法采用通配符泛型类型时,可以访问或修改集合,但不能同时访问或修改集合。(凯西和伯特) 据我所知,方法do1有,因此d2只能被访问,不能被修改。方法d2具有,因此可以访问和修改c2,并且没有编译错误。 通用指南
在这个例子中:假设我需要一个selectionSort的版本,它可以使用调用方提供的外部可比性来处理任何类型T。 第一次尝试: 假设我有: 定义的车辆类别 创建VehicleComparator实现比较器,同时根据车辆的价格比较车辆。 创建的卡车扩展车辆 实例化卡车[]arr;VehicleComparator MyComparator 现在,我有: 这个宣言会起作用,但我不完全确定我一直在做什么
类型参数T不应由最终的类型整数限定。不能进一步扩展Final类型 为什么使用final类型作为通配符的上限完全可以,但对类型参数抛出警告?为什么Java甚至允许通配符被最终的上层类型所约束?
问题内容: 与完全跳过它们相比,在类中使用通配符类型的泛型有什么优势吗? 问题答案: 有很多优点。 他们不会像使用原始类型那样产生编译器警告 它们提供了更多的类型安全性。例如,考虑是否是。如果您使用代替,则可以执行以下操作: 即使该列表仅 应 包含s。如果返回,则您将无法添加 任何 内容(除外),因为列表类型未知。 他们记录的东西与原始类型完全不同,即使用某种 未知但特定的类型进行输入 。