要“修复”代码,您需要使用通用绑定:
public void interfaceIsTheArgument(List extends Weapon> w) { ... }
...
interfaceIsTheArgument(new ArrayList extends Weapon> ());
interfaceIsTheArgument(new ArrayList());
关键原因是List< Gun>不是List< Weapon>的子类.此代码可以说明这一事实的原因:
List guns = new ArrayList();
// If List was a super type of List, this next line would be allowed
List weapons = guns; // Won't compile, but let's assume it did
weapons.add(new Knife()); // Compiles, because Knife is a Weapon
Gun gun = guns.get(0); // Oops! guns.get(0) is a Knife, not a Gun!
通过使用绑定,我们说我们将接受任何属于武器子类的泛型类型.使用边界可能非常强大.这种绑定是一个上限 – 我们将顶级类指定为Weapon.
还有一个下限,它使用以下语法:
List super Weapon> // accept any type that is a Weapon or higher in the class hierarchy
那么,何时使用每一个?记住这个词PECS:“制片人延伸,消费者超级”.这意味着在代码的生产者端(创建对象的地方)使用扩展,并且在代码的消费者端(使用对象的地方)使用超级.一旦你尝试了几次,你将通过经验了解为什么它运作良好.