我有超过250个子类需要由它们组成的实例,我不能坐在那里哄骗并粘贴new Class();
250次。无论如何使用Reflection来创建类的实例?制作实例时不需要构造函数。
感谢。
答案 0 :(得分:3)
我真的不理解你,但我试着猜测(未经测试):
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();
-------^^^^^^^^-------
}
}
}
查看Creating New Class Instances
编辑: 也许 http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#forName(java.lang.String)
Class.forName("mypackage.MyClassname");
答案 1 :(得分:2)
首先,您需要get all the subclasses。这个特别的答案看似合法,虽然我自己没有测试过。
然后,当有必须传递的构造函数的参数时,遍历这些类并使用Class.newInstance
(无参数构造函数)或Class.getConstructor
和Constructor.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
这将获取子类,迭代它们,并创建每个子类的实例。这里有一些例外,我没有做任何事情。你可能还需要做一些演员(虽然我不认为你必须这样做)。
编辑:我上面的回答显然会导致一些虚假的类加载。创建一组子类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));
}
然后这些行:
for (Class<? extends SubType> subType : subTypes) {
someTypes.add(subType.newInstance());
}
成为这个:
for (Class<?> subType : subTypes) {
someTypes.add((SomeType) subType.newInstance());
}
答案 2 :(得分:0)
您可以执行以下操作:
Class instantiableClass = Class.forName("package.subpackage.ClassName");
Object instance = instantableClass.newInstance();
仅当您的类只有默认构造函数或public zero args构造函数时才有效。如果需要,代码可以循环,推广或复制。
对于更一般的解决方案this可能会帮助您理解为什么不可能。你可以用你认识的任何课程做任何你想做的事,或者知道他们的名字,或者可以从任何来源访问他们的名字,或者以任何方式提供这些最低限度的信息。
但是如果不了解那些课程,那几乎是不可能的。您必须在当前类路径中寻找所有类,然后chceck它们的继承树以符合您的特定类。
答案 3 :(得分:0)
这是一大堆代码,用于加载包的所有类,为它创建新实例并将它们放在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对我来说是org / commandes。
我不知道这是否是正确的方法,但这是我在servlet中实现Command设计模式(类似插件的实现)的唯一方法。