我有超过250个子类需要创建实例,而我不能坐在那里并且复制粘贴250次new Class();
。使用反射是否有办法来创建这些类的实例?当创建实例时不需要构造函数。
谢谢。
我有超过250个子类需要创建实例,而我不能坐在那里并且复制粘贴250次new Class();
。使用反射是否有办法来创建这些类的实例?当创建实例时不需要构造函数。
谢谢。
我真的不太理解你,但我会尽力猜测(未经过测试):
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();
-------^^^^^^^^-------
}
}
}
Class.forName("mypackage.MyClassname");
首先,你需要获取所有的子类。那个特定的答案似乎是合法的,虽然我自己没有测试过。
然后遍历这些类并使用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
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());
}
这是一段代码,用于加载一个包中的所有类,创建它们的新实例并将它们放入哈希映射表中(我的所有类都继承自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 中实现命令设计模式(类似插件实现)的唯一方法。
您可以按照以下步骤进行:
Class instantiableClass = Class.forName("package.subpackage.ClassName");
Object instance = instantableClass.newInstance();
只有当您的类仅具有默认构造函数或公共零参数构造函数时才有效。如果需要,可以循环、泛化或复制代码。
更通用的解决方案 this 可以帮助您了解为什么不可能。您可以使用任何已知类或已知其名称的类,或者可以从任何源访问其名称,或者以任何方式提供这些最小信息。
但是,如果没有关于那些类的任何知识,几乎是不可能的。您必须寻找当前类路径中的所有类,然后检查它们的继承树以符合特定类。