У меня есть две петли, которые я пытаюсь реорганизовать в один метод. Петли уведомляют слушателей разных типов и объявляются как общие. Я думал, что смогу сделать это с некоторым отражением, но, похоже, я не могу об этом подумать.Литье класса и общего типа для использования в параметризованном типе
Вот мое сообщение класса и интерфейса слушателя:
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 и в документах, пытаясь понять это. Кажется, что есть много сообщений о дженериках, но я не могу найти то, что я могу связать с моим конкретным вариантом использования.
Cheers.
EDIT:
решаемые с помощью принятого ответа.
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()));
}
}
Спасибо, это, кажется, почти довести меня в рабочее состояние. Очень умно. Я удалил параметр 'Class', поскольку он не нужен. Я также добавил '' в мою подпись класса. Я получаю сообщение об ошибке: «Метод notifyMessageListeners (Message, ValueGetter ) в типе MyService не применим для аргументов (Message, new ValueGetter () {})'. Любое предложение о том, что может быть неправильным? –
span
Думаю, я мог бы это решить. См. Сообщение для редактирования, пожалуйста, если вы считаете, что это правильно. – span
@rattmuff Да, это правильно: поскольку 'ValueGetter' параметризуется в том же типе' T', что и 'Class', передача класса стала ненужной. –
dasblinkenlight