< /code>
Так что я могу позвонить < /p>
JcUEventQueue.addListener(String.class, e -> System.out.println("GOT INCOMING EVENT: " + e));
и иметь e как тип, который я ожидаю обратно (в данном случае E имеет класс String ). [ as opposed to receiving an Object when not using type bounding ].
Problem
- I do NOT want to create a new JcUEventQueue for every possible type, (I want to keep using one the one central static Class)
- I still want to accept ANY reference Тип
< /code>
Но Java не примет это, потому что типы несовместимы. pmessage имеет другой тип, чем требуется методом receationintermessage . Это очевидно из -за Follwing:
Теперь, внутренне, pmessage является объектом:
static private ArrayList notifyListeners(final Class pClazz, final Object pMessage) {
и даже если я определил повышение событий с помощью параметра статического типа t pmessage :
static private ArrayList notifyListeners(final Class pClazz, final T pMessage) {
T, переданный в метод, не соответствовал бы t, который примет метод Cay -method eCeaturnalmessage (различные источники определения).
Я также не могу отбрасывать переменную pmessage во что -либо полезное, чтобы назвать
stireceineinternalmessage ; Решение
До сих пор я обнаружил только Reflection в качестве рабочего инструмента для этой проблемы:
final String methodName = "receiveInternalMessage";
sListenerMethod = JcIEventListener.class.getDeclaredMethod(methodName, Object.class);
sListenerMethod.invoke(listener, pMessage); // use reflection to we can force an object into a T
< /code>
Вопрос < /h2>
Вы, ребята, знаете о каких -либо других возможных решениях этой проблемы, без создания и управления ListSt для каждого возможного типа?public interface JcIEventListener {
void receiveInternalMessage(final T pMessage);
}
< /code>
и < /p>
package jc.lib.observer.events;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import jc.lib.gui.window.dialog.JcUDialog;
public class JcUEventQueue {
static private final ConcurrentHashMap>> sClass2Listeners = new ConcurrentHashMap();
static private Method sListenerMethod;
static {
final String methodName = "receiveInternalMessage";
try {
sListenerMethod = JcIEventListener.class.getDeclaredMethod(methodName, Object.class);
} catch (NoSuchMethodException | SecurityException e) {
System.err.println("Critical shutdown while initializing " + JcUEventQueue.class.getCanonicalName() + ": Method not found: " + methodName);
JcUDialog.showError(e);
System.exit(1);
}
}
static public void addListener(final Class pTriggerOnClass, final JcIEventListener pListener) {
if (pTriggerOnClass == null) throw new IllegalArgumentException("Triggering Class cannot be null!");
if (pListener == null) throw new IllegalArgumentException("Listener cannot be null!");
// T gets lost here
final List clazz = pMessage.getClass();
while (true) { // trigger on class and all of its super-classes
// I removed the code to also cover all interfaces, as this would bloat this question up
notifyListeners(clazz, pMessage);
clazz = clazz.getSuperclass();
if (clazz == null) break;
}
}
static private ArrayList notifyListeners(final Class pClazz, final T pMessage) {
if (pClazz == null) return null;
// if (pMessage == null) return null; // explicitly allow sending of null message Objects
final List
Подробнее здесь: https://stackoverflow.com/questions/797 ... neric-type