How to create instances of all subclasses

*爱你&永不变心* 提交于 2019-12-07 16:30:49

问题


I have over 250 subclasses that need instances made of them, and I can't sit there and coy and paste new Class(); 250 times. Is there anyway using Reflection to make an instnace of the classes? No constructor is needed when making the instance. Thanks.


回答1:


I really don't undesrtand you, but I try to guess (not tested):

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

Look at Creating New Class Instances

EDIT: May be http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#forName(java.lang.String)

Class.forName("mypackage.MyClassname");



回答2:


First, you'll need to get all the subclasses. That particular answer seems legitimate, though I haven't tested it myself.

Then iterate through the classes and create the instances using either Class.newInstance (no-args constructors) or Class.getConstructor and Constructor.newInstance when there are parameters for the constructor that you have to pass. The final code will look something like this:

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

This will get the subclasses, iterate over them, and create an instance of each one. There are some exceptions here that I'm not doing anything with. You may also have to do some casting (though I don't think you have to).

Edit: My answer above will apparently cause some spurious class loading. Create your set of subclasses like this instead:

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

Then these lines:

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

Become this:

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



回答3:


That's a chunk of code to load all the classes of a package, to create new instances for it and to put them in an hashmap (all my classes inherits from 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();
        }
    }

Here, COMMAND_DIRECTORY is org/commandes for me.

I don't know if this is the right way to do it, but it's the only way i found to implement the Command design pattern (plugin-like implemented) in a servlet.




回答4:


You can do as follows:

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

Only works if your classes have only a default constructor, or public zero args constructor. The code may be looped, generalized or reproduced if you need.

For more general solution this may help you understand why it is not possible. You can do whatever you want with any classes you know, or know their name, or can access their name from any source, or be provided with such minimum information in any way.

But without any knowledge of that classes, it is hardly possible. You would have to seek for all classes in current classpath and then chceck their inheritance tree for compliance with your particular class.



来源:https://stackoverflow.com/questions/12538761/how-to-create-instances-of-all-subclasses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!