user6818621
user6818621

Reputation:

Instantiate all children of a given abstract parent class dynamically

Is there a way to instantiate all children of an abstract class dynamically?

What I have currently is similar to this:

public class CommandHandler {

    private Command info        = new Info();
    private Command prefix      = new Prefix();
    private Command roll        = new Roll();
    private Command coin        = new Coin();
    private Command invite      = new Invite();
    private Command quit        = new Quit();
    private Command restart     = new Restart();

}

With the abstract parent class being something like this:

public abstract class Command {

    protected String name;
    protected String arguments;

    protected abstract void execute();

}

But what if I want to instantiate all classes that extend Command without typing them all out individually and adding to the list every time I add a command?

And if I can instantiate them dynamically, can I also manipulate them dynamically? i.e. add each class to a list once it has been instantiated.

Or is there a better design to use that accomplishes what I want in a simpler way?

EDIT: @Ash's solution works perfectly in an IDE, but not when using a jar. All you have to do to make it work in both is change

classPathList.addAll(ClasspathHelper.forClassLoader());

to

classPathList.addAll(ClasspathHelper.forJavaClassPath());

Hope it helps someone!

Upvotes: 4

Views: 640

Answers (1)

Ji aSH
Ji aSH

Reputation: 3457

If you use maven (if not, you should :p), add the following dependency :

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.10</version>
</dependency>

Then you can list the class you want with the following code (assuming you have a constructor with no parameters) :

public class Loader {

    public static void main(String[] args) {
        try {
            Set<URL> classPathList = new HashSet<URL>();
            classPathList.addAll(ClasspathHelper.forClassLoader());
            Set<Class<? extends Command>> result = new Reflections(new ConfigurationBuilder().setScanners(new SubTypesScanner()).setUrls(classPathList)).getSubTypesOf(Command.class);

            List<Command> commands = new ArrayList<Command>();

            for (Class<? extends Command> c : result) {
                System.out.println(c.getSimpleName());
                commands.add(c.newInstance());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Upvotes: 3

Related Questions