我有两个循环,我正在尝试重构为单个方法。循环通知不同类型的侦听器,并将它们声明为通用。我以为我可以做一些反思,但我似乎无法理解它。
这是我的消息类和监听器接口:
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()));
}
}
答案 0 :(得分:2)
以下是如何修复您的第一次尝试:
首先,定义一个用于调用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);
}
});