我试图了解下限和上限通配符的行为。
尝试编译以下代码时遇到问题。
Collection<? extends Object> c = new ArrayList<Object>();
c.add(new Object()); // Compile time error
为了弄清楚问题,我还尝试了下限通配符。幸运的是或不幸的是,代码可以很好地编译,但是却造成了很多混乱。
Collection<? super Object> c = new ArrayList<Object>();
c.add(new Object()); // Compiles fine
有人可以解释一下这两个代码段如何工作。如果有人可以提供其他示例/链接,那就太好了。
如果我在上面做错了什么,请纠正我。
提前致谢。
?
表示“未知类型”。
Collection<? extends Object>
表示某种对象的集合。此“某种类型”可以是作为其子类Object
或Object
自身的任何类型。究竟是哪种类型?编译器不知道。
当您尝试向Object
集合中添加新内容时,您不能这样做。这是因为集合的类型未知。它可以是一个ArrayList<String>
。它可以是一个HashSet<Integer>
。所以编译器说
“如果收藏是
ArrayList<String>
什么?你不能放在Object
那里!”
基本上,编译器太谨慎了,您不能这样做。
Collection<? super Object>
表示某种对象的集合。这种“某种类型的”可以是任何类型,它是一个超类Object
或Object
本身。在这里只能是一件事-
Object
,因为Object
它没有超类。因此,您可以Object
向收藏夹中添加新商品。
即使Object
具有超类,您仍然可以添加new Object()
。让我们称为的超类Object
MyClass
。现在,该集合可以是MyClass
或的集合Object
。无论是哪种,您都可以为其添加一个Object
。
在这个例子中:假设我需要一个selectionSort的版本,它可以使用调用方提供的外部可比性来处理任何类型T。 第一次尝试: 假设我有: 定义的车辆类别 创建VehicleComparator实现比较器,同时根据车辆的价格比较车辆。 创建的卡车扩展车辆 实例化卡车[]arr;VehicleComparator MyComparator 现在,我有: 这个宣言会起作用,但我不完全确定我一直在做什么
问题内容: 该问题的答案表明,当方法采用通配符通用类型时,可以访问或修改集合,但不能同时访问或修改集合。(凯西和伯特) 这是什么意思?“ 当方法采用通配符通用类型时,可以访问或修改集合,但不能同时访问两者 ”? 据我所知,方法do1具有d2只能访问但不能修改。d2的方法使c2可以被访问和修改,并且没有编译错误。 通用准则 问题答案: 该问题的答案表明,当方法采用通配符通用类型时,可以访问或修改集合
null 为什么我不能在MyList中添加对象。因为如果我们使用super,这意味着这个列表可以包含在Java类的继承制度中等于或高于number的对象。因此应该按照该语句在列表中添加新的Object()。 多谢了。
问题内容: 我真的很难理解通配符参数。我对此有一些疑问。 作为类型参数只能在方法中使用。例如:我不能使用类型参数定义类。 我了解上限。 表示:“ 如果有实现该 接口的 对象, 则将打印。 ” 我对有点问题。表示:“ 如果具有 或扩展的任何类 (的后代 ), 则将打印。 ” 纠正我哪里出错了。 简而言之,只有或或或或可用作定义泛型类的类型参数。只能用于方法 更新1: 根据Ivor Horton的书,
这是我试图理解的编译器行为的一个过度简化版本: 在上面的代码片段中,是一个类型范围比HouseCat接口允许的类型范围更广的引用,即: 如果我尝试执行类似的操作,编译器会告诉我不满足类型参数的约束。那么,,至少是潜在的。 编译器不会让我创建违反类型参数约束的实例,但我对它使用作为引用上限的行为感到困惑。在(,)之间有一个无效的类型范围,那么编译器为什么不拒绝这个引用定义呢? 澄清:我的问题不是关于
这个问题的答案表明,当方法采用通配符泛型类型时,可以访问或修改集合,但不能同时访问或修改集合。(凯西和伯特) 据我所知,方法do1有,因此d2只能被访问,不能被修改。方法d2具有,因此可以访问和修改c2,并且没有编译错误。 通用指南