Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将对象强制转换为给定的泛型类型,以便将此对象传递给方法_Java_Generics_Lambda_Interface_Casting - Fatal编程技术网

Java 如何将对象强制转换为给定的泛型类型,以便将此对象传递给方法

Java 如何将对象强制转换为给定的泛型类型,以便将此对象传递给方法,java,generics,lambda,interface,casting,Java,Generics,Lambda,Interface,Casting,我有一个类“Event”,它有一个泛型参数-T。 它是事件的类型,并且始终是一个接口。 事件侦听器必须实现它想要“侦听”的事件类型 例如: public class GuiHandler implements Startup, GuiChanged 但只有一种方法可以注册此事件侦听器。只需获取它实现的所有事件,并使用事件侦听器实例或方法引用调用“register”方法 我试图创建一个“EventManager”类,该类可以检测给定对象的类是否实现了“event.getType()(返回事件的T

我有一个类“Event”,它有一个泛型参数-T。 它是事件的类型,并且始终是一个接口。 事件侦听器必须实现它想要“侦听”的事件类型

例如:

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));
}
公共静态无效寄存器(对象侦听器){
for(事件:Event.EVENTS)
if(listener.getClass().isInstance(event.getType()))
register(event.getType().cast(listener));
}
但出于某种原因,它说

类型中的方法寄存器(捕获#3-of?) 事件不适用于参数 (捕获4-of?)

事件是这样进行的:

new Event<>(GuiChanged.class, (listeners) -> 
    (/*some event specific arguments*/) -> {
        for (GuiChanged event : listeners) {
            event.onGuiSchnged(/*some event specific arguments*/);
        }
    });
新事件(GuiChanged.class,(侦听器)->
(/*一些特定于事件的参数*/)->{
for(GuiChanged事件:侦听器){
onguischned(/*一些特定于事件的参数*/);
}
});
建造商是:

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;
    }
公共事件(类类型、函数){
this.type=type;
this.functionToUse=functionToUse;
EVENTS=Arrays.copyOf(EVENTS,EVENTS.length+1);
EVENTS[EVENTS.length-1]=此;
}

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

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

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

    // rest ommitted for brevity
}
然后,您的
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);
        }
    }
} 

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

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

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

    // rest ommitted for brevity
}
然后,您的
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);
        }
    }
} 

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

好的,解决方案很简单。我所要做的就是从“EVENTS”数组中删除
,然后使用“isAssignableFrom”检查侦听器是否实现了给定的事件类型。现在可以了

好的,解决方法很简单。我所要做的就是从“EVENTS”数组中删除
,然后使用“isAssignableFrom”检查侦听器是否实现了给定的事件类型。现在可以了

你能展示
事件#寄存器
的方法声明吗?它是
公共无效寄存器(T listener)
你能展示
事件#寄存器
的方法声明吗?它是
公共无效寄存器(T listener)
这不是我真正想要的。我想让事件可以直接执行监听器,而不需要任何“eventdata”和“fire”方法。当前可以这样运行:
GuiChanged.EVENT.getInvoker().onGuiChanged(/*一些事件数据*/)functionouse
execution。这不是我真正想要的。我想让事件可以直接执行监听器,而不需要任何“eventdata”和“fire”方法。当前可以这样运行:
GuiChanged.EVENT.getInvoker().onGuiChanged(/*一些事件数据*/)functionouse