类型安全和通配符泛型:了解禁止修饰符
在 Java 中使用泛型集合时,通配符泛型的概念可以引入某些最初看起来可能违反直觉的限制。一个典型的例子是无法向具有通配符泛型类型的 Java 集合添加值。
考虑以下代码片段:
List<? extends Parent> list = ...; Parent p = factory.get(); // returns concrete implementation list.set(0, p); // fails here: set(int, ? extends Parent) cannot be applied to (int, Parent)
为什么此代码无法编译?答案在于通配符泛型强制执行的固有安全机制。
无限制检索和限制添加原则
通配符泛型类型,用 ? 表示扩展 Parent,表示属于 Parent 接口后代的元素列表。虽然它允许不受限制地检索这些元素,但类型安全规定了向集合添加值的限制。
如果允许编译代码,它将允许将 Parent 实例分配给列表中的元素。但是,此操作可能会破坏类型安全。
考虑以下场景:
List<Child> childList = new ArrayList<>(); childList.add(new Child()); List<? extends Parent> parentList = childList; parentList.set(0, new Parent()); Child child = childList.get(0); // No! It's not a child! Type safety is broken...
在此场景中,Child 对象列表被转换为列表的 ?扩展父级。随后将 Parent 实例分配给列表的第一个元素违反了类型安全,因为结果列表包含不是有效 Child 实例的元素。
确保不可变类型安全
通过禁止向通配符泛型集合添加值,Java 强制执行不可变类型安全。这可确保列表的元素始终遵守其声明类型所施加的约束。
如果没有此限制,类型安全性将受到损害,从而导致潜在的错误和意外行为。
以上是为什么我无法将元素添加到具有通配符泛型类型(`?extends Parent`)的 Java 集合中?的详细内容。更多信息请关注PHP中文网其他相关文章!