3

I'm trying to extract all classes that implement an interface and put these in a Set. However, that interface is Parameterized and I'd like to communicate that it's all subclasses, regardless of their "parameter" I want, using a wildcard or something like that. However, I still need access to that parameter when going through the Set. (Btw I'm using the Reflections library)

The interface I'm trying to get subclasses of:

public interface Shouter<T> {
    void shout(T dataObj);
}

What I'm trying to do (which I can't get to work)

private static Set<Class<? extends Shouter<?>>> extractShouters(String rootPackage) {
    Reflections reflections = new Reflections(rootPackage);
    return (Set<Class<? extends Shouter<?>>>) reflections.getSubTypesOf(Shouter<?>.class);
}

I'm getting an error in the last bit there, the "Shouter<?>.class", and I know that what I've written wont compile but I don't know how else. Now, I'm relatively new to Reflections, so I don't know if just addressing it as RAW would solve it and still give me access to the parameter.

The Set I mentioned earlier:

private Set<Class<? extends Listening<?>>> listeners;
private Set<Class<? extends Shouter<?>>> shouters;
  • 1
    Do you understand that when you have a `Shouter>`, you can’t invoke the `shout` method with a non-`null` argument anyway, unless you resort to unchecked operations or raw types? So, go ahead and use `Shouter.class`, you’re abandoning the generic type system anyway. – Holger May 23 '22 at 09:23
  • Well. Yes. That is exactly what I don't want to do and why I wrote the question. How do I avoid referencing them as the RAW type? – G. B. Wanscher May 23 '22 at 15:18
  • 2
    You don’t. Generics is a compile-time feature. Reflection is a runtime feature. They don’t work together. What if a particular implementation class implements `Shouter` whereas the `WarpDrive` class doesn’t exist in your compile-time setup? So you will never get something better than `Shouter>` and while some classes, e.g. `class X implements Shouter`, can be queried for the actual type argument, others, like `class Y implements Shouter` can not, because they don’t even know. Neither can you query the class of `Shouter s = x -> {};` for its actual type argument. – Holger May 23 '22 at 15:39

0 Answers0