使用参数化参数调用方法

Invoking methods with parametrized arguments

我目前正在构建一个事件系统来处理我的应用程序中的一些事件。 EventDispatcher 调用带有参数的方法,这些参数可从事件的 class 分配。这适用于非参数化参数,但我找不到使用参数化参数(具有通用类型的参数)执行此操作的解决方案。
我如何过滤那些

这是我的 Dispacher 的一小段摘录:

private final Event event; // custom Event-class
private final Map<Object, List<Method>> subscriber;

/* snip */

@Override
public void run() {
    subscriber.forEach((sub, methods) -> methods.stream()
            // filter for matching event methods
            .filter(m -> {
                // returns true, even if generic types do not match
                return m.getParameters()[0].getType().isAssignableFrom(event.getClass());
            })
            .forEach(m -> {
                try {
                    m.invoke(sub, event);
                } catch (IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    LOGGER.error("...", e);
                }
            })
    );
}

注意:订阅者映射中的给定方法已经具有所需的 return 类型、1 参数和标识事件方法的注解。

编辑: 来自评论: 问题是,当我检查 Event<Integer> isAssignableFrom( Event<String> )

时,Java return 是真的

经过一些测试和进一步阅读后,我想出了一个测试,看看我是否可以通过 Types:

来匹配泛型
private static boolean test(Type type1, Type type2) {
    if (type1 == type2) return true;
    if (type1.getTypeName().equals(type2.getTypeName())) {
        if (type1 instanceof ParameterizedType || type2 instanceof ParameterizedType) {
            if (type1 instanceof ParameterizedType && type2 instanceof ParameterizedType) {
                Type[] type1Params = ((ParameterizedType) type1).getActualTypeArguments();
                Type[] type2Params = ((ParameterizedType) type2).getActualTypeArguments();
                if (type1Params.length != type2Params.length) return false;
                for (int i = 0; i < type1Params.length; i++) {
                    if (!test(type1Params[i], type2Params[i])) return false;
                }
                return true; // all generic types in both types are equal pairwise
            }
            return false; // one with generic type and one without
        }
        return true; // both no generic types
    }
    return false; // not equal by name
}

我的结果:

  • 您可以将方法的两个参数与此匹配,因为 Method can return a Type[] with getGenericParameterTypes.
  • 您无法检查两个实例是否具有相同的通用类型。因为您通过 getClass 获得类型,所以只有您拥有实例的 Class 的类型将在没有通用类型的情况下返回。
    Type Erasure