java - 如何将对象转换为给定的泛型类型,以便我可以将此对象传递给方法

标签 java generics lambda interface casting

我有一类“Event”,带有一个通用参数 - T。 它是事件类型并且始终是一个接口(interface)。 事件监听器必须实现它想要“监听”的事件类型。

例如:

public class GuiHandler implements Startup, GuiChanged

但是只有一种方法可以注册此事件监听器。只需获取它实现的所有事件并使用事件监听器实例或方法引用调用“register”方法即可。

我正在尝试创建一个“EventManager”类,它可以检测给定对象的类是否实现“event.getType()(返回事件 T)”,如果实现,则将对象转换为此事件类型并在事件中注册。

public static void register(Object listener) {
    for (Event<?> event : Event.EVENTS)
        if (listener.getClass().isInstance(event.getType()))
            event.register(event.getType().cast(listener));
}

但由于某种原因它说

The method register(capture#3-of ?) in the type Event is not applicable for the arguments (capture#4-of ?)

事件是这样制作的:

new Event<>(GuiChanged.class, (listeners) -> 
    (/*some event specific arguments*/) -> {
        for (GuiChanged event : listeners) {
            event.onGuiSchnged(/*some event specific arguments*/);
        }
    });

构造函数是:

public Event(Class<T> type, Function<T[], T> functionToUse) {
        this.type = type;
        this.functionToUse = functionToUse;
        EVENTS = Arrays.copyOf(EVENTS, EVENTS.length + 1);
        EVENTS[EVENTS.length - 1] = this;
    }

请帮忙。我相信这是可能的。

最佳答案

在我看来,你应该使用不同的设计。目前,您的Event类负责保存其所有监听器,但理论上事件应该只保存相关的事件数据。

public class Event<T> {
    private Class<T> eventClass;
    private T data;

    // rest ommitted for brevity
}

EventListener保存它应该处理的相关事件类型和处理方法本身。

public interface EventListener<T> {
    Class<T> getType();
    void notify(T event);
}

您的EventManager然后负责保存监听器和触发相关事件。我用过Map此处可快速识别应通知特定事件的监听器。

public class EventManager {

    private Map<Class<?>, EventListener<?>> listeners = new HashMap<>();

    public registerListener(EventListener<?> listener) {
        // ...
    }

    public void fire(Event<?> event) {
        EventListener<?> listener = listeners.get(event.getEventClass());
        if(listener != null) {
            listener.notify(event);
        }
    }
} 

当然,你只能持有一个EventListener上例中的每种类型(为简单起见)。使用List<EventListener<?>>相反,如果您想支持每个类多个监听器。此外,abobe 类只是原型(prototype),需要额外的转换,但这些是类型安全的,因为 Event<T> 的泛型类型始终引用与 getEventClass() 相同的类.

示例用例:

  • 对于您的 Activity :new Event(data, GuiChangedData.class);
  • 相关监听器:

    public class GuiChangedListener implements EventListener<GuiChangedData> {
        // ...
    }
    

如果您需要更多信息,请随时询问。

关于java - 如何将对象转换为给定的泛型类型,以便我可以将此对象传递给方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55261390/

相关文章:

java - Android 中的 SuperNotCalledException?

java - 通用类型 x 通用参数 : Building a "very generic" structure

c# - 获取泛型类的子类型列表

c# - 需要帮助将 C# foreach 循环转换为 lambda

c# - C# 中的高级列表比较

c++ - 更改版本后降级 g++

java - 传递给maven插件的参数的优先级是什么?

java - 自动调整大小的 JFrame 容器

java - 矩形的交集java

c# - 将两个 List<T> 组合在一起,使用 LINQ 根据实例成员合并 T 的实例