2

So I have a few classes:

public abstract class IEventExecutor<A extends Event> implements EventExecutor {
    
        public final Class<A> type;
    
        public IEventExecutor(Class<A> type){
            this.type = type;
        }
    
        public abstract void event(A a);
    
        @Override
        public void execute(Listener listener, Event event) throws EventException{
            event((A) event);
        }
    }

public class PluginExtension extends Plugin {

    public void register(IEventExecutor<? extends Event> executor){
        EventExecutor e = executor;
        EventManager.registerEvent(executor.type, EventPriority.NORMAL, e, system);
    }

}

The registerEvent method:

void registerEvent(@NotNull Class<? extends Event> class_, @NotNull Listener listener, @NotNull EventPriority eventPriority, @NotNull EventExecutor eventExecutor, @NotNull Plugin plugin);

In registerEvent Class<? extends Event> is needed, but executor.type provides Class<capture of ? extends Event>. I have no idea, why the "capture of" is provided, and this also means I have no Idea, how to solve this. Can someone explain what is happening, and if there is a way to solve this?

  • Can you show the declaration of `registerEvent`? – Sweeper Sep 05 '21 at 00:25
  • I added the declaration to the question. – BrokenStudio Sep 05 '21 at 00:29
  • The issue here is that the Java compiler, which uses `` as the name of the type `?` in the register method internally, doesn't know and furthermore can't infer that the type passed in to that method is actually the same as the one expected by the `registerEvent` method and therefore throws that exception. See also [this excellent answer](https://stackoverflow.com/a/40403745/1377895). – Roman Vottner Sep 05 '21 at 00:59
  • 1
    @RomanVottner N.B. that no exception is being thrown; this is a compile-time error. – chrylis -cautiouslyoptimistic- Sep 05 '21 at 02:19
  • @chrylis-cautiouslyoptimistic- you are of coure right. Should have read through the comment once more – Roman Vottner Sep 05 '21 at 02:21
  • Please provide a complete example which reproduces the error. – tgdavies Sep 05 '21 at 03:08
  • With the given information it is not possible to reproduce the actual problem. I tried creating the necessary classes in IntelliJ and the thing apparent is that your call of the `EventManager.registerEvent(...)` method does not pass a listener to it as required by the given method definition. Other than that my IDE doesn't see a problem here with the classes I created in the process of reproducing your issue. Assigning `executor` to `e` is uncessary though and you should not cast the event to `A` directly but reuse the class available `type.cast(event)` in the execute method – Roman Vottner Sep 05 '21 at 12:39

1 Answers1

1

It's not clear from your question exactly what code the error is associated with. However, your PluginExtension class looks a little off to me. Try making the register method generic:

public class PluginExtension extends Plugin {

    public <T extends Event> void register(IEventExecutor<T> executor){
        EventExecutor e = executor;
        EventManager.registerEvent(executor.type, EventPriority.NORMAL, e, system);
    }

}

Or perhaps make the entire class generic.

The same goes for the registerEvent method. Change it to:

<T extends Event> void registerEvent(
    @NotNull Class<T> class_,
    @NotNull Listener listener,
    @NotNull EventPriority eventPriority,
    @NotNull EventExecutor eventExecutor,
    @NotNull Plugin plugin
);

(Note, however, that you posted code that calls a three-argument version of EventManager.registerEvent but gave us the signature of a five-argument version.)

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521