相关疑难解决方法(0)

无法从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
查看次数

为什么我不能将Collection <GenericFoo>转换为Collection <GenericFoo <?>>

问题的关键是,为什么这会导致编译时错误?

List<Collection> raws = new ArrayList<Collection>();
List<Collection<?>> c = raws; // error
Run Code Online (Sandbox Code Playgroud)

背景

我理解为什么泛型一般不协变.如果我们能够分配List<Integer>List<Number>,我们会暴露自己ClassCastExceptions异常:

List<Integer> ints = new ArrayList<Integer>();
List<Number> nums = ints; // compile-time error
nums.add(Double.valueOf(1.2));
Integer i = ints.get(0); // ClassCastException
Run Code Online (Sandbox Code Playgroud)

我们在第2行得到一个编译时错误,以避免我们从第4行的运行时错误.这是有道理的.

List<C>List<C<?>>

但是这个怎么样:

List<Collection> rawLists = new ArrayList<Collection>();
List<Collection<?>> wildLists = rawLists; // compile-time error

// scenario 1: add to raw and get from wild
rawLists.add(new ArrayList<Integer>());
Collection<?> c1 = wildLists.get(0);
Object o1 = c1.iterator().next();

// scenario 2: add to wild …
Run Code Online (Sandbox Code Playgroud)

java generics

17
推荐指数
1
解决办法
168
查看次数

标签 统计

generics ×2

java ×2

casting ×1

raw-types ×1

unbounded-wildcard ×1