lundi 8 octobre 2018

Can reflection be used to get a concrete implementing type (e.g. Class extends MyInterface?> )?

My goal is to reflect all the static classes in a container class and collect them into a map of simpleName -> class.

This can be done 'by hand' with no problem, but I'd really like to do it programatically.

For example, given:

public interface MyInterface {
    void doThing();
}

And a class containing several classes implementing that interface

public class MyStuff {
    public static class One implements MyInterface {...}
    public static class Two implements MyInterface {...}
    public static class Three implements MyInterface {...}
}

The following manually created map works A-OK.

public void demo(String jsonString) {
    Map<String, Class<? extends MyInterface>> myMap = ImmutableMap.of(
        "One", One.class,
        "Two", Two.class,
        "Three", Three.class,
    )

}

And I can use it for useful things such a deserialization with Gson:

MyInterface object = new Gson().fromJson(jsonString, myMap.get("One"))

Now, what I'd like to do is not build that map by hand, but instead use reflection to build it.

Ideally, something along the lines of:

Map<String, Class<? extends MyInterface>> options = new HashMap<>();
for (Class<?> cls : MyStuff.class.getDeclaredClasses()) {
    options.put(cls.getSimpleName(), cls)
}

But this doesn't compile, as getDeclaredClasses is fixed to Class<?>.

Interestingly, Java seems to have all the information it needs during runtime. I can print out each class and see that it is the correct implementing class of MyInterface. I feel like I should be able to get the types I need. However, I can't figure out how to make that final compile-time hop to get a Class<? extends MyInterface>

Is this possible in Java?





Aucun commentaire:

Enregistrer un commentaire