java - 绑定添加到列表时的一般误解
问题描述
这是一个通配符问题。
我的目的是创建一个列表,其中包含一个具有扩展示例的泛型类型的类:
所以这是结构:
public class Event<T extends ActionType>{
}
public abstract class ActionType{
}
//**many** classes that extends ActionType class
这是一个包含从ActionType扩展的类的列表
private List<Event<ActionType>> list = ArrayList<>();
Event<RightClick> event = new Event<>(xPosition, yPosition, delay, new RightClick(robot), clicks, robot);
list.add(event);
我知道我不能这样做以确保我可以添加扩展项目:
private List<Event<ActionType>> list = ArrayList<>();
但我可以做些什么来将这些项目添加到同一个列表中。
为了解决我的问题,我使用了通配符选择器?
List<Event<? extends ActionType>>
解决方案
解释
泛型是不变的。AList<Event<ActionType>>
不会接受Event<RightClick>
,只有Event<ActionType>
。
了解泛型并调整泛型类型限制。
如果泛型是 covariant,那么您可以给期望 aList<Animal>
的人List<Dog>
,然后将Cat
s 添加到它。这会导致堆损坏,因为它dogs.get(0)
可能突然变成Cat
.
一个例子:
List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog());
List<Animal> animals = dogs; // pretend this would work
animals.add(new Cat()); // would be legit
Dog dog = dogs.get(1); // should be safe, but is cat, heap corruption
AList<Animal>
明确表示此列表必须接受所有动物,包括猫。但 aList<Dog>
仅限于狗。这两个列表的行为不同,它们有不同的限制,因此您不能将一个用于另一个。与 a Dog
who is an不同Animal
,a List<Dog>
is not an List<Animal>
,这就是协变和不变性的含义。
解决方案
“接受任何ActionType
,我不在乎”的正确工具是通配符。所以要么去
List<Event<? extends ActionType>>
要不就
List<Event<?>>
因为Event
该类已经指定了T extends ActionType
限制。
使用该类型,您将能够向其添加各种Event
s:
Event<RightClick> rightClick = ...
Event<LeftClick> leftClick = ...
Event<MiddleClick> middleClick = ...
list.add(rightClick);
list.add(leftClick);
list.add(middleClick);
作为?
通配符的结果,您将无法在编译时知道实际类型,因此:
Event<?> event = list.get(0); // unknown which exact type
您所知道的?
是它至少是extends ActionType
,因此您将能够使用 给出的各种方法ActionType
,但仅在RightClick
示例中没有介绍。这将需要显式转换(由instanceof
检查保护),尽管如果您必须在那里使用右键单击特定的东西,我会质疑您的设计。
推荐阅读
- javascript - 将画布元素附加到组
- android - 改造寻找不存在的参数?
- r - 在 Github 和 RStudio 之间推拉
- javascript - 在 Django 中使用输入范围值更改图像大小
- python - 在管理页面上捕获 IntegrityError 的最佳方法?
- r - R 将某些列中的所有值偏移一个单位
- reactjs - 在 ReactJs 中呈现的元素列表中发送请求
- prolog - 警告:Prolog 中的单例变量错误消息
- windows-10 - Windows 10 计算器使用哪个 API 来获取货币汇率?
- android - 我的片段android中的NavArgs问题