Java 将元素添加到wildchar列表会导致编译错误
我有一个列表包含将来的任务,将来的类型未知,所以我创建了一个通配符类型为Java 将元素添加到wildchar列表会导致编译错误,java,generics,Java,Generics,我有一个列表包含将来的任务,将来的类型未知,所以我创建了一个通配符类型为?的列表,但是当我向列表中添加元素时,会发生编译错误 代码如下: private List<Pair<String, Future<?>>> futureTasks = Collections.synchronizedList( new ArrayList<Pair<String, Future<?>>>(8)); // taskId
?
的列表,但是当我向列表中添加元素时,会发生编译错误
代码如下:
private List<Pair<String, Future<?>>> futureTasks = Collections.synchronizedList(
new ArrayList<Pair<String, Future<?>>>(8));
// taskId is a string
futureTasks.add(Pair.makePair(taskId, getExecutors().submit(
new Callable<String>() {
public String call() {
try {
return exportAccountSrcTask(tmpFile); // return a string
} catch (Exception e) {
logger.error("failed to export account src", e);
}
return null;
}}))
);
私有列表>>
不适用于参数(成对)
出现错误是因为
对
不是对>
。然后您就可以向它添加一对了
编辑:
为了更好地解释这一点,可以考虑尝试将对象分配给变量,而不是将其添加到列表中。如果我们有一个列表
,我们只能添加一个T
对象。因此,情况也是如此:
Pair<String, Future<String>> pairOfStringAndFutureOfString;
Pair<String, Future<?>> pairOfStringAndFutureOfSomething;
// incompatible types
pairOfStringAndFutureOfSomething = pairOfStringAndFutureOfString;
这个变量名很有意思,但我希望它能准确地描述这里发生的事情。之前,第二个类型参数正好是Future
。现在,我们说它是“某种未知类型,它是或扩展了未来
。例如,它可能是未来
,它可能是未来
,甚至可能是我的专业未来
我们自愿放弃有关此变量类型的一些信息,以便放宽可分配给它的内容。现在,这是合法的:
pairOfStringAndSomethingThatIsAFutureOfSomething = pairOfStringAndFutureOfString;
编译器通过防止“消耗”此未知类型来防止早期的“堆污染”情况:
要了解有关这些检索的更多信息,请参阅此帖子:由于对
不是对
,因此您将得到一个错误。然后您将能够向其添加对
编辑:
为了更好地解释这一点,请考虑尝试将对象分配给变量,而不是将其添加到列表中。如果我们有一个列表
,则只有当对象是T
时,我们才能添加该对象。因此,这实际上是相同的情况:
Pair<String, Future<String>> pairOfStringAndFutureOfString;
Pair<String, Future<?>> pairOfStringAndFutureOfSomething;
// incompatible types
pairOfStringAndFutureOfSomething = pairOfStringAndFutureOfString;
这个变量名很有意思,但我希望它能准确地描述这里发生的事情。之前,第二个类型参数正好是Future
。现在,我们说它是“某个未知类型,它是或扩展了Future
。例如,它可以是Future
,也可以是Future
,甚至可以是MySpecialFuture
我们自愿放弃一些关于这个变量类型的信息,以便放松可以分配给它的内容。现在,这是合法的:
pairOfStringAndSomethingThatIsAFutureOfSomething = pairOfStringAndFutureOfString;
编译器通过防止“消耗”此未知类型来防止早期的“堆污染”情况:
要了解有关这些检索的更多信息,请参阅以下帖子:为什么不能将其声明为列表
?未来可能不确定,然后将其声明为列表
。至于为什么不能使用通配符“”和@MattBall添加()
,这实际上是一个不同的问题,因为它涉及一个嵌套的通配符。为什么不能将其声明为List
?未来可能不确定,然后将其声明为List
。至于为什么不能使用通配符“.add()”
:和@MattBall,这实际上是一个不同的问题,因为它涉及一个嵌套的通配符。@jamee查看我的编辑,如果您还有其他问题,请告诉我。似乎我可以将Pair和Pair添加到List@jamee是的,没错,因为它们都是Pair@jamee重要的是要认识到顶级通配符和嵌套通配符之间有很大的区别。有关更多信息,请参阅本文:@jamee查看我的编辑,如果您还有其他问题,请告诉我。似乎我可以将Pair和Pair添加到List@jamee是的,这是正确的,因为它们都是Pair@jamee重要的是要认识到顶级通配符和嵌套通配符之间有很大的区别。有关更多信息,请参阅本文:
//compiler error - nothing can be legally passed into setRight
pairOfStringAndSomethingThatIsAFutureOfSomething.setRight(futureOfSomething);