Guava Multimaps 通配符 putAll
Guava Multimaps wildcard putAll
使用 Guava 的 Multimap 遇到泛型问题
class Foo{
...
private Multimap<Baz,? extends Bar> stuff;
...
public void overWriteStuff(Multimap<Baz,? extends Bar> newstuff){
this.stuff.clear();
this.stuff.putAll(newStuff);
}
}
这对我来说看起来很简单,stuff
和参数 newstuff
都有相同的类型,但我得到了一个泛型相关的编译器异常:
The method putAll(Multimap<? extends Baz,? extends capture#8-of ? extends Bar>) in the type
Multimap<Baz,capture#8-of ? extends Bar> is not applicable for the arguments (Multimap<Baz,capture#9-of ?
extends Bar>)
谁能看到我的泛型问题在哪里?
原始声明中的 ?
通配符无法匹配参数中的 ?
通配符。它们可以是 Bar
的任何子类(或 Bar
本身),并且它们不必匹配。
您需要在 Foo
上引入泛型类型参数来替换通配符,以便它们表示相同的类型。
class Foo<T extends Bar>{
在变量声明中:
private Multimap<Baz, T> stuff;
并且在方法参数中:
public void overWriteStuff(Multimap<Baz, T> newstuff){
顺便说一句,这与 Java 的泛型有关,但与 Guava 无关。我可以用 Map
替换 Multimap
.
来复制错误
问题是 ? extends Bar
意味着 "some specific (but unknown) subtype of Bar
"。您不知道,对于 class 中的字段或您的方法的参数,multimap 持有什么实际类型的值。
例如,如果您有两个 classes Foo extends Bar
和 Blah extends Bar
,您可以将 Multimap<Baz, Foo>
分配给 stuff
并传递 Multimap<Baz, Blah>
作为 newstuff
到您的方法。如果 stuff.putAll(newstuff)
被允许,那么 stuff
是一个多重映射,声称其所有值都是 Foo
的实例,而实际上其中一些值是 [=21] 的实例=].
也许您实际上只想 stuff
成为 Multimap<Baz, Bar>
?在这种情况下,它的值可以是任何类型的 Bar
并且您的方法可以正常工作。正如@rgettman 提到的,另一种选择是引入类型变量 T extends Bar
以确保 stuff
和 newstuff
的值都 相同 Bar
的子类型;你做什么取决于你在这里实际想要完成的事情。
使用 Guava 的 Multimap 遇到泛型问题
class Foo{
...
private Multimap<Baz,? extends Bar> stuff;
...
public void overWriteStuff(Multimap<Baz,? extends Bar> newstuff){
this.stuff.clear();
this.stuff.putAll(newStuff);
}
}
这对我来说看起来很简单,stuff
和参数 newstuff
都有相同的类型,但我得到了一个泛型相关的编译器异常:
The method putAll(Multimap<? extends Baz,? extends capture#8-of ? extends Bar>) in the type
Multimap<Baz,capture#8-of ? extends Bar> is not applicable for the arguments (Multimap<Baz,capture#9-of ?
extends Bar>)
谁能看到我的泛型问题在哪里?
原始声明中的 ?
通配符无法匹配参数中的 ?
通配符。它们可以是 Bar
的任何子类(或 Bar
本身),并且它们不必匹配。
您需要在 Foo
上引入泛型类型参数来替换通配符,以便它们表示相同的类型。
class Foo<T extends Bar>{
在变量声明中:
private Multimap<Baz, T> stuff;
并且在方法参数中:
public void overWriteStuff(Multimap<Baz, T> newstuff){
顺便说一句,这与 Java 的泛型有关,但与 Guava 无关。我可以用 Map
替换 Multimap
.
问题是 ? extends Bar
意味着 "some specific (but unknown) subtype of Bar
"。您不知道,对于 class 中的字段或您的方法的参数,multimap 持有什么实际类型的值。
例如,如果您有两个 classes Foo extends Bar
和 Blah extends Bar
,您可以将 Multimap<Baz, Foo>
分配给 stuff
并传递 Multimap<Baz, Blah>
作为 newstuff
到您的方法。如果 stuff.putAll(newstuff)
被允许,那么 stuff
是一个多重映射,声称其所有值都是 Foo
的实例,而实际上其中一些值是 [=21] 的实例=].
也许您实际上只想 stuff
成为 Multimap<Baz, Bar>
?在这种情况下,它的值可以是任何类型的 Bar
并且您的方法可以正常工作。正如@rgettman 提到的,另一种选择是引入类型变量 T extends Bar
以确保 stuff
和 newstuff
的值都 相同 Bar
的子类型;你做什么取决于你在这里实际想要完成的事情。