[英]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.