0

I'm trying to instantiate and register listener classes in a loop, based on a list of event classes. I'm trying to use a list such as:

static final Class[] USER_EVENTS_HANDLED = {
    FirstEvent.class,
    SecondEvent.class
};

I have a bunch of listener classes, one for each:

FirstEventListener extends MyAbstractListener<T extends MyEvent>
SecondEventListener extends MyAbstractListener<T extends MyEvent>

I'm currently manually registering the event class and listener class explicitly:

eventManager.registerListener(FirstEvent.class, new FirstEventListener());
eventManager.registerListener(SecondEvent.class, new SecondEventListener());

I'm trying to not duplicate the event name twice, for maintainability. I build the name of the listener class from the event class, but I'm struggling to come up with the right way to create a new instance of the listener using that. First tried newInstance, but then realized generics had to be treated specially. I got something like this snippet of code from somewhere:

private static class ListenerGenerator<E> {
    E generateListener(Class<E> clazz, Constructor constructor) throws Exception {
        return (E) constructor.newInstance();
    }
}

So to make that work, I tried calling "getConstructor", along with some other approaches, but that keeps resulting in a NoSuchMethod error.

What's the simplest approach to accomplish my goal?

NOTE: This is not a duplicate of the question just asking about creating an instance of a generic class in Java. It's a more specific case requiring a significantly more complex solution.

sdanzig
  • 3,818
  • 1
  • 19
  • 23
  • The title is a bit convoluted, but I'm not sure if I can edit that, and I think the description of what I'm trying to accomplish in the body text is clear. – sdanzig Jan 09 '19 at 00:17
  • 1
    *What's the simplest approach to accomplish my goal?* Duplicate the event name twice. Done. – Elliott Frisch Jan 09 '19 at 00:23
  • I'm not sure where you are stuck, how are you calling `generateListener`? – Jorn Vernee Jan 09 '19 at 00:42
  • @JornVernee I'm calling it with listenerGenerator.generateListener(listenerClass, listenerClass.getConstructor()); – sdanzig Jan 09 '19 at 03:33
  • @ElliottFrisch So you don't know how to instantiate that listener class using reflection? – sdanzig Jan 09 '19 at 03:46
  • I do know how to instantiate the listener class using reflection, you asked what was the simplest approach. Reflection is not the simplest approach. Not even close. – Elliott Frisch Jan 09 '19 at 03:47
  • @ElliottFrisch I understand what you're saying, and ultimately might have decided, yeah, even if I scuttle this crap into a separate method/class/etc, it's still something other people need to understand. But it wasn't what I was trying to do. I was wanting to avoid the duplication. I thought that was clear when I wrote "I'm trying to not duplicate the event name twice". I wouldn't have needed to spend time on StackOverflow trying to ask for help on this otherwise. – sdanzig Jan 09 '19 at 04:03
  • Fine. Include enough code to make this a MCVE and I'll actually write an answer showing you how you can do this with reflection. It will **require** quite a bit of code. And you will have to modify your method(s). Let's start with the most basic part. `E` has no restrictions on it as your generic type. Should it not relate in some way to a `MyAbstractListener`? – Elliott Frisch Jan 09 '19 at 04:14
  • Also, please expand upon *I build the name of the listener class from the event class and instantiate it, but I'm struggling to come up with the right way to create a new instance of the listener using that.* The first part is directly contradicted by the second. – Elliott Frisch Jan 09 '19 at 04:15
  • https://stackoverflow.com/a/50572534/2970947 – Elliott Frisch Jan 09 '19 at 04:36
  • @ElliottFrisch Thanks, but I'm going to need to take a break from this. I've been putting in a lot of extra hours, including some time trying to get this working, and possibly wasn't figuring it out because I'm not feeling right. Sorry I didn't supply enough information to ask my question. I'll try again when I'm feeling better and have more time. – sdanzig Jan 09 '19 at 04:52
  • I fixed the typing mistake you pointed out by the way (removed "and instantiated it"). Thanks for spotting that. – sdanzig Jan 09 '19 at 04:59
  • Get some rest. Ultimately, I think you want a `Class super MyAbstractListener super MyEvent>> cls` and `cls.getConstructor(new Class[0]).newInstance(new Object[0]);` be sure to expand upon your question though. Also, specify the version of Java you're using. Because `Class.newInstance()` was deprecated in Java 9. – Elliott Frisch Jan 09 '19 at 05:04

0 Answers0