Java泛型通配符问题 [英] Java Generics Wildcards Question
问题描述
public interface Handler< T extends Serializable> {
void handle(T t);
$ b 在另一个类中,我定义了一个将String映射到集合的multimap
private Multimap< String,Handler<扩展Serializable>> multimap =
ArrayListMultimap.create();
现在,当我尝试使用multimap进行操作时,出现编译器错误。我的第一次尝试看起来像这样:
public< T extends Serializable> void doStuff1(String s,T t){
Collection< Handler< T>> collection = multimap.get(s); (Handler< T>处理程序:集合){
handler.handle(t);
}
}
导致以下错误。
类型不匹配:无法从Collection< Handler转换<?扩展Serializable>>
到Collection< Handler< T>>
之后,我试着像这样编码
$ b public void doStuff2(String s,Serializable serializable){
Collection< Handler<扩展Serializable>> collection = multimap.get(s); (Handler< ;? extends Serializable> handler:collection)
{
handler.handle(serializable);
}
}
不幸失败:
类型
Handler<捕获#1中的方法句柄(capture#1 of?extends Serializable)扩展Serializable>不适用于参数
(可序列化)
任何帮助将不胜感激。感谢。
更新:
我设法解决这个问题的唯一方法是通过压制编译器警告。给定以下处理程序:
public interface Handler< T extends Event> {
void handle(T t);
Class< T>的getType();
}
我可以编写事件总线。
public class EventBus {
private Multimap< Class<>,Handler<>> multimap = ArrayListMultimap.create();
public< T扩展事件> void subscribe(Handler< T> handler){
multimap.put(handler.getType(),handler);
$ b $ @SuppressWarnings({rawtypes,unchecked})
public void publish(Event event){
Collection< Handler<>> ; collection = multimap.get(event.getClass());
for(Handler handler:collection){
handler.handle(event);
}
}
}
我想没有办法处理这个更少或甚至没有@SuppressWarnings?
解决方案如果您定义了以下内容,它将会更好:
private Multimap< String,Handler< Serializable>> multimap =
ArrayListMultimap.create();
更新:解释您的问题。
当你有类似的东西时。
private Multimap< String,Handler<扩展Serializable>>多重映射;
这意味着multimap可以接受任何 Handler< N>
其中 N扩展可序列化
。让我们考虑它将包含类型 Handler< Foo>
的值和类型 Handler< Bar>
的值。 Foo
和 Bar
是不相关的,并且不会相互延伸。
在你的函数中,你想用一个类型来表示 Handler的所有可能值的类型。扩展Serializable>
,你试图表达一个类型,它同时是 Foo
和 Bar
,但没有这种类型。
这解释了编译器的问题。现在删除这个-1,如果你认为我是正确的,就投我的答案。
I'm facing some problems with Generics when using Google Guava's excellent Multimap. I have a type Handler defined as such
public interface Handler<T extends Serializable> {
void handle(T t);
}
In another class I've defined a multimap that maps a String to a collection of Handlers.
private Multimap<String, Handler<? extends Serializable>> multimap =
ArrayListMultimap.create();
Now when I try to do stuff with the multimap, I'm getting compiler errors. My first attempt looked like this:
public <T extends Serializable> void doStuff1(String s, T t) {
Collection<Handler<T>> collection = multimap.get(s);
for (Handler<T> handler : collection) {
handler.handle(t);
}
}
which resulted in the following error.
Type mismatch: cannot convert from Collection<Handler<? extends Serializable>>
to Collection<Handler<T>>
Afterwards, I tried to code it like this
public void doStuff2(String s, Serializable serializable) {
Collection<Handler<? extends Serializable>> collection = multimap.get(s);
for (Handler<? extends Serializable> handler : collection) {
handler.handle(serializable);
}
}
which unfortunately failed as well:
The method handle(capture#1-of ? extends Serializable) in the type
Handler<capture#1-of ? extends Serializable> is not applicable for the arguments
(Serializable)
Any help would be greatly appreciated. Thanks.
Update:
The only way I have managed to fix this is by suppressing compiler warnings. Given the following handler:
public interface Handler<T extends Event> {
void handle(T t);
Class<T> getType();
}
I can write the event bus as such.
public class EventBus {
private Multimap<Class<?>, Handler<?>> multimap = ArrayListMultimap.create();
public <T extends Event> void subscribe(Handler<T> handler) {
multimap.put(handler.getType(), handler);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void publish(Event event) {
Collection<Handler<?>> collection = multimap.get(event.getClass());
for (Handler handler : collection) {
handler.handle(event);
}
}
}
I guess there's no way to handle this with less or even without @SuppressWarnings?
解决方案 It will work better if you define:
private Multimap<String, Handler<Serializable>> multimap =
ArrayListMultimap.create();
Update: Explaination of your problem.
When you have something like ..
private Multimap<String, Handler<? extends Serializable>> multimap;
It means that multimap can accept ANY Handler<N>
where N Extends Serializable
. Let's consider that it will contain a value of type Handler<Foo>
and a value of type Handler<Bar>
. Foo
and Bar
are unrelated and do not extend from each other.
When in your function you want to use a type to represent the type of all the possible values of Handler<? extends Serializable>
, you are trying to express a type which is at the same time Foo
and Bar
, but there is no such a type.
This explains your problem with the compiler. Now remove this "-1" and vote for my answer if you think I am correct.
这篇关于Java泛型通配符问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!