簡體   English   中英

用於參數化類型的類和泛型類型轉換

[英]Class and generic type casting to use in parameterised type

我有兩個循環,試圖將其重構為一個方法。 循環會通知偵聽器不同的類型,並且將它們聲明為泛型。 我以為我可以反思一下,但是似乎無法解決。

這是我的消息類和偵聽器接口:

public class Message {

    private RequestType type; // Enum
    private String data; 
    ...
}

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

這是循環:

...
// Notification is an Enum
for (IRequestListener<?> listener : listeners) {
    IRequestListener<Notification> notificationListener = 
        (IRequestListener<Notification>) listener;

    notificationListener.resultUpdated(Notification.valueOf(message.getData()));
}

...

for (IRequestListener<?> listener : listeners) {
        IRequestListener<Integer> notificationListener = 
            (IRequestListener<Integer>) listener;

        notificationListener.resultUpdated(Integer.valueOf(message.getData()));
}

這是我嘗試解決的鑄造嘗試,這顯然是錯誤的:

...

notifyMessageListeners(Notification.class, essage)

...

notifyMessageListeners(Integer.class, message);

...

private void notifyMessageListeners(Class clazz, Message message) {
    LinkedList<IRequestListener<?>> listeners = 
         requestListenerMap.get(message.getType());

    for (IRequestListener<?> listener : listeners) {

        // How to solve this cast?
        // Error: unknown class: 'clazz'
        IRequestListener<clazz> notificationListener = 
            (IRequestListener<clazz>) listener;

        // How to solve the valueOf? Need to cast to a class which has valueOf()?
        // Error: cannot resolve method valueOf
        notificationListener.resultUpdated(clazz.valueOf(message.getData()));
     }
}

這是我解決問題的一般嘗試,這也是錯誤的:

private void notifyMessageListeners(Message message) {

    LinkedList<IRequestListener<?>> listeners = 
        requestListenerMap.get(message.getType());

    for (IRequestListener<?> listener : listeners) {
        // Causes error
        // resultUpdated (<?>)  in IRequestListener cannot be applied to (java.lang.String)
        listener.resultUpdated(message.getData());
    }
}

我在SO和文檔上花了一些時間試圖解決這個問題。 關於泛型的文章似乎很多,但是我找不到與我的特定用例有關的東西。

干杯。

編輯:

在已接受答案的幫助下解決。

notifyMessageListeners(message, new IValueGetter<T>() {
    public T getValue(String data) {
        return (T) Notification.valueOf(data);
    }
});

private void notifyMessageListeners(Message message, IValueGetter<T> getter) {
    LinkedList<IRequestListener<?>> listeners = 
        requestListenerMap.get(message.getType());
    for (IRequestListener<?> listener : listeners) {
        IRequestListener<T> notificationListener = (IRequestListener<T>) listener;
        notificationListener.resultUpdated(getter.getValue(message.getData()));
    }
}

以下是解決您的首次嘗試的方法:

首先,定義一個用於調用valueOf的接口(您可以通過使用反射來避免這種情況,但是我認為“無反射”方法更干凈)

interface ValueGetter<T> {
    T getValue(String data);
}

該通用接口使您可以將一段代碼傳遞給notifyMessageListeners以便該方法將回調您以從字符串中提取所需的值。

private void notifyMessageListeners(Message message, ValueGetter<T> getter) {
    LinkedList<IRequestListener<?>> listeners = 
         requestListenerMap.get(message.getType());

    for (IRequestListener<?> listener : listeners) {
        IRequestListener<T> notificationListener = 
            (IRequestListener<T>) listener;
        notificationListener.resultUpdated(getter.getValue(message.getData()));
     }
}

調用notifyMessageListeners ,需要傳遞ValueGetter<T>的實例,如下所示:

notifyMessageListeners(message, new ValueGetter<T>() {
    public T getValue(String data) {
        return (T) Notification.valueOf(data);
    }
});

notifyMessageListeners(message, new ValueGetter<T>() {
    public T getValue(String data) {
        return (T) Integer.valueOf(data);
    }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM