在下面的代码中,get()调用它并将结果分配给类型为的变量List<List<?>>.get()返回a List<List<T>>并在类型参数T设置为的实例上调用?,因此它应该适合.
import java.util.List;
class Test {
void foo(NestedListProducer<?> test) {
List<List<?>> a = test.get();
}
interface NestedListProducer<T> {
List<List<T>> get();
}
}
Run Code Online (Sandbox Code Playgroud)
但IntelliJ IDEA和Oracle的javac1.7.0_45版都拒绝我的代码无效.这是'javac'的错误消息:
java: incompatible types
required: java.util.List<java.util.List<?>>
found: java.util.List<java.util.List<capture#1 of ?>>
Run Code Online (Sandbox Code Playgroud)
为什么这段代码无效,即如果允许则会出错?
这?是一个任何类型的通配符.一个?不能与另一个相同?,因为另一个?可能是任何其他类型,并且它们不匹配.您必须使用泛型来表示类型是相同的:
// Make this generic
<A> void foo(NestedListProducer<A> test) {
List<List<A>> a = test.get();
}
Run Code Online (Sandbox Code Playgroud)
List<List<T>>List<T>表示您可以从中读取或写入新的列表List<T>,并且类似地表示您可以从中读取或写入新的List<List<?>>列表。奇怪的是你可以将任何类型的列表转换为. 例如你可以写:List<?>List<T>?SList<?>
void foo(List<String> a, List<Integer> b, List<List<?>> out) {
List<?> unknownA = a;
List<?> unknownB = b;
out.add(a);
out.add(b);
}
Run Code Online (Sandbox Code Playgroud)
如果您可以将 a 转换List<List<T>>为 a List<List<?>>,则可以foo使用 a 进行调用List<List<PeanutButter>>,然后向其中添加字符串和整数列表。
一般来说,人们遇到这种情况是因为他们试图表达这样的概念:他们想要一个类型无关紧要的子集合的集合。如果这就是您想要的,您可以将类型从 更改List<List<?>>为List<? extends List<?>>,它表达了我可以读取但不能写入的子列表列表的概念。List<List<T>>将 a 转换为 a是合法的List<? extends List<?>>。
| 归档时间: |
|
| 查看次数: |
1467 次 |
| 最近记录: |