与列表中的泛型方法参数类型的接口

时间:2013-11-18 14:43:21

标签: java generics

我有一个HashMap,它将特定的RequestType链接到单独的LinkedLists。列表由具有泛型类型的接口组成。我没有问题添加到地图中的列表,但我似乎无法将列表从地图中删除。

我会告诉你我的两次尝试,并有相应的错误。首先,当我想在界面中调用该方法时,我将向您显示界面和我的Map。

public interface IRequestListener<Result> {
    public void resultUpdated(Result result);
}

private HashMap<RequestType, LinkedList<IRequestListener<?>>> requestListenerMap = 
    new HashMap<RequestType, LinkedList<IRequestListener<?>>>();

在以下代码中,RequestType和Notification是两个简单的枚举。

这是第一次尝试:

Notification notification = Notification.AVOID;
LinkedList<IRequestListener<?>> listeners = 
    requestListenerMap.get(RequestType.NOTIFICATION);
for(IRequestListener<?> listener : listeners) {
    listener.resultUpdated(notification); // ERROR ON THIS LINE
}

导致以下错误:

The method resultUpdated(capture#1-of ?) in the type 
IRequestListener<capture#1-of ?> is not applicable for 
the arguments (Notification)

这是第二次尝试:

Notification notification = Notification.AVOID;
LinkedList<IRequestListener<Notification>> listeners = 
    requestListenerMap.get(RequestType.NOTIFICATION); // ERROR ON THIS LINE
for(IRequestListener<Notification> listener : listeners) {
    listener.resultUpdated(notification);
}

导致以下错误:

Type mismatch: cannot convert from LinkedList<IRequestListener<?>> 
to LinkedList<IRequestListener<Notification>>

我认为我正在被遗传/铸造问题绊倒,这些问题对于泛型来说很棘手,但我无法弄清楚如何。我不想扩展通知,因为此时接口中的Result可以是Notification或Integer。稍后我还可以添加一个List作为结果的可能性。

干杯。

1 个答案:

答案 0 :(得分:1)

听起来您希望约束Result类型参数以扩展Notification

private HashMap<RequestType, LinkedList<IRequestListener<? extends Notification>>> 
    requestListenerMap = new HashMap<>(); // Assuming Java 7

...

LinkedList<IRequestListener<? extends Notification>> listeners = 
    requestListenerMap.get(RequestType.NOTIFICATION);
for(IRequestListener<? extends Notification> listener : listeners) {
    listener.resultUpdated(notification);
}

现在,如果这不适合地图声明 - 因为你想为其他条目存储其他列表 - 你可能需要一个不安全的演员:

private HashMap<RequestType, LinkedList<IRequestListener<?>>> requestListenerMap = 
    new HashMap<RequestType, LinkedList<IRequestListener<?>>>();

...

LinkedList<IRequestListener<?>> listeners = 
    requestListenerMap.get(RequestType.NOTIFICATION);
for (IRequestListener<?> listener : listeners) {
    // Note that this cast is unsafe.
    IRequestListener<? extends Notification> notificationListener = 
        (IRequestListener<? extends Notification>) listener;
    notificationListener.resultUpdated(notification);
}

从根本上说,不能安全地执行此操作,因为执行时类型不包含类型参数。但如果不恰当,请致电ClassCastException时获得resultUpdated