相关疑难解决方法(0)

List <Dog>是List <Animal>的子类吗?为什么Java泛型不是隐式多态的?

我对Java泛型如何处理继承/多态性感到困惑.

假设以下层次结构 -

动物(父母)

- (儿童)

所以假设我有一个方法doSomething(List<Animal> animals).根据所有继承和多态的规则,我会假设a List<Dog> a List<Animal>而a List<Cat> a List<Animal>- 所以任何一个都可以传递给这个方法.不是这样.如果我想实现这种行为,我必须明确告诉该方法接受一个Animal的任何子类的列表doSomething(List<? extends Animal> animals).

我知道这是Java的行为.我的问题是为什么?为什么多态通常是隐含的,但是当涉及泛型时必须指定它?

java generics polymorphism inheritance

727
推荐指数
10
解决办法
10万
查看次数

无法从List <List>转换为List <List <?>>

原始列表转换为List<?>正常.为什么原始列表列表不能转换为列表List<?>

{   // works
    List raw = null;
    List<?> wild = raw;
}
{   // Type mismatch: cannot convert from List<List> to List<List<?>>
    List<List> raw = null;
    List<List<?>> wild = raw;
}
Run Code Online (Sandbox Code Playgroud)

背景故事(缓解xy问题):

我正在使用的API返回List<JAXBElement>.我碰巧知道它总是如此List<JAXBElement<String>>.我计划循环并构建自己的List<String>,但我在写时试图修复(但不是抑制)原始类型编译器警告List<JAXBElement> raw = api();.

我试过了:

List<JAXBElement<?>> raw = api();
List<JAXBElement<?>> raw = (List<JAXBElement<?>>) api();
Run Code Online (Sandbox Code Playgroud)

但这些给出了类型不匹配错误.

有趣的是,这没有任何警告或错误:

for (JAXBElement<?> e : api()) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

java generics casting raw-types unbounded-wildcard

25
推荐指数
1
解决办法
2561
查看次数

从List <Optional>转换为List <Optional <?>>是否安全?

如果您在Java中具有原始类型,则可以使用无界通配符安全地将其分配/转换为相同类型.例如,a List可以安全地转换为a List<?>,这会消除其原始特性,并允许您以安全(类型检查)的方式使用它1.

在另一方面,Java并不让您从投List 本身参数与原始类型,比如List<Optional>同类型的参数列表中采用无界通配符,像List<Optional<?>>.

您仍然可以通过完全丢弃原始数据List并再次备份(通过赋值隐式)来执行此操作:

List<Optional> rawOptionalList = null;
List<Optional<?>> wildcardOptionalList = (List)rawOptionalList;
Run Code Online (Sandbox Code Playgroud)

当然,这会触发关于未经检查的转换(从ListList<Optional<?>>)的警告.

在我看来,虽然这种转换可以保证安全:List<Optional<?>>不仅仅像List<Optional>将原始产品Optional转换Optional<?>为安全一样安全吗?


1 ...但你永远无法在此列表中添加任何内容,因为没有任何内容与?add(?)方法的捕获相匹配.这是你为安全付出的代价.

java generics

10
推荐指数
1
解决办法
117
查看次数