如何创建所有子类的实例(How to create instances of all subclas

2019-09-22 18:42发布

我有超过250的子类需要使他们的情况下,我不能坐在那里,忸怩和粘贴new Class(); 250倍。 反正是有使用反射,使类的instnace? 制作实例时无需构造函数。 谢谢。

Answer 1:

我真的不undesrtand你,但我会尝试猜测(未测试):

public class Test {
    public static void main(String[] args) {
        Class[] classes = new Class[]{Class1.class, Class2.class, Class3.class};
        for (Class cls : classes) {
            Object myObject = cls.newInstance();
            -------^^^^^^^^-------
        }
    }
}

看看创建新的类实例

编辑:可能是http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#forName(java.lang.String )

Class.forName("mypackage.MyClassname");


Answer 2:

首先,你需要得到所有的子类 。 这个特别的答案似乎是合法的,虽然我没有测试它自己。

然后通过遍历类,并使用可以创建实例Class.newInstance (无参数的构造函数)或Class.getConstructorConstructor.newInstance当有对构造函数的参数,你必须通过。 最终代码会是这个样子:

Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeType>> subTypes = 
        reflections.getSubTypesOf(SomeType.class);
Set<SomeType> someTypes = new HashSet<SomeType>(subTypes.size());
for (Class<? extends SubType> subType : subTypes) {
    someTypes.add(subType.newInstance());
}
// Do something with someTypes here

这将让子类,在它们之间迭代,并创造每一个实例。 这里有一些例外,我不是跟做任何事情。 您可能还必须做一些铸造(虽然我不认为你必须)。

编辑:上面我的回答显然会导致一些虚假的类加载。 创建子集是这样,而不是 :

Reflections reflections = new Reflections(...); //see in other use cases
Set<String> subTypeFqns = reflections.getStore().getSubTypesOf(SomeClass.class.getName());
Set<Class<?>> subTypes = new HashSet<Class<?>>();
for (String fqn : subTypeFqns) {
    subTypes.add(Class.forName(fqn));
}

然后,这些行:

for (Class<? extends SubType> subType : subTypes) {
    someTypes.add(subType.newInstance());
}

成为这个:

for (Class<?> subType : subTypes) {
    someTypes.add((SomeType) subType.newInstance());
}


Answer 3:

这是一段代码,加载一个包的所有类别,为它创建新实例,并把它们放在一个HashMap中(我所有的类都是从COMMANDE继承):

    this.actions = new HashMap<String, Commande>();

    ServletContext sc = this.getServletContext();

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    URL res = classLoader.getResource(COMMAND_DIRECTORY);
    File[] list = new File(res.getFile()).listFiles();
    String className = "";
    for (File f : list) {
        className = f.getName().replaceAll(".class$", "");
        try {
            Class<?> classe = Class.forName("org.commandes." + className);
            if (classe.getSuperclass() == Commande.class) {
                Commande c = (Commande) classe.newInstance();
                this.actions.put(c.getName(), c);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

在这里,COMMAND_DIRECTORY是我组织/ commandes。

我不知道这是做正确的方式,但它是我发现执行命令设计模式(插件类实现)在servlet的唯一途径。



Answer 4:

你可以做如下:

Class instantiableClass = Class.forName("package.subpackage.ClassName");
Object instance = instantableClass.newInstance();

只有当你的类只有一个默认的构造函数,或公共零参数的构造函数的作品。 该代码可以循环,全身性或转载,如果您需要。

欲了解更多通用的解决方案这可能会帮助你理解为什么它是不可能的。 你可以做任何你想要的,你知道任何类,或者知道他们的名字,或者可以从任何来源访问他们的名字,或提供以任何方式这样的最低限度的信息。

但是,如果没有那类的任何知识,这几乎是不可能的。 你将不得不寻求在当前classpath的所有类,然后chceck他们继承树是否符合您的特定类。



文章来源: How to create instances of all subclasses