动态地实例化给定抽象父类的所有子项

时间:2017-01-16 14:07:49

标签: java

有没有办法动态地实例化抽象类的所有子项?

我目前的情况与此类似:

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();

}

抽象父类是这样的:

public abstract class Command {

    protected String name;
    protected String arguments;

    protected abstract void execute();

}

但是如果我想实例化所有扩展Command的类而不单独输入它们并且每次添加命令时都添加到列表中会怎么样?

如果我可以动态实例化它们,我还可以动态操作它们吗?即,在实例化后,将每个类添加到列表中。

或者是否有更好的设计可以用更简单的方式完成我想要的设计?

编辑:@ Ash的解决方案在IDE中完美运行,但在使用jar时则不行。所有你需要做的就是改变它

classPathList.addAll(ClasspathHelper.forClassLoader());

classPathList.addAll(ClasspathHelper.forJavaClassPath());

希望它有所帮助!

1 个答案:

答案 0 :(得分:4)

如果你使用maven(如果没有,你应该:p),添加以下依赖:

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

然后,您可以使用以下代码列出所需的类(假设您有一个没有参数的构造函数):

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();
        }
    }
}