2011-04-06 88 views
14

我查了一下语法并搜索了api,但是仍然对这个过程感到困惑。我也搜索了Stackoverflow。加载一个类并动态创建一个对象的正确方法是什么?换句话说,我希望用户指定他们想要创建什么类型的对象,然后创建该类型的对象。我不想要菜单,因为我希望他们能够选择当前目录中的任何类。用Java动态加载一个类

+0

您是否试图从binary.class文件或类名加载类? – 2011-04-06 19:09:37

+0

@JustinWaugh嗨,贾斯汀,是接受的答案适合加载一个.class文件? – leaf 2015-11-28 14:00:07

回答

15

假设类具有无参数的构造函数,最简单的方法是 -

Object newObject = Class.forName(strFullyQualifiedClassName).newInstance(); 

参考 - java.lang.Class

+0

如果它有arg,我该如何在类上调用一个方法 - 我如何仅仅通过类的名字来施放newObject?当我尝试调用类型为Object的类的方法时,它告诉我方法对于对象未定义。 – rubixibuc 2011-04-06 19:15:50

+2

如果您在编译时不知道类的类型,您将不得不使用反射来查找和调用方法。如果构造函数有一个参数,您可以在从Class.forName返回的类上使用'getDeclaredConstructor()',如从Mike Samuel – 2011-04-06 19:17:27

+0

+1到Justin的答案所示。另外,实际上,不可能对课程一无所知,因为实际使用它非常困难。让这些未知类实现特定的接口通常是一个好策略。然后您可以通过接口引用这些对象,以便您可以调用它们上的方法等。 – 2011-04-06 19:28:02

4

ClassLoader.loadClass将加载一个类。你得到一个类加载器myClass.getClassLoader(),你应该回落到ClassLoader.getSystemClassLoader(),如果这是null。

一旦你有一个类实例,你可以通过getDeclaredConstructor(...)得到它的构造函数。 所以,如果你有一个public class MyClass使用构造像public MyClass(String) { ... }然后

Class<MyClass> clazz = MyClass.class; 
Constructor<MyClass> ctor = clazz.getDeclaredConstructor(String.class); 
MyClass instance = ctor.newInstance("foo"); 

以上忽略了一堆可能的例外。

+0

是MyClass的一个实例还是该类的静态引用?有什么办法可以通过将其名称作为字符串传递给方法来获取类的构造函数吗?或者有类似的方法吗? – rubixibuc 2011-04-07 00:35:16

+0

'MyClass'是本例中类的名称。一个类可以有多个构造函数(或者没有接口);没有一个类的“构造函数”。 – 2011-04-07 01:08:23

+0

'MyClass.class'可能是混淆语法。这只是引用“MyClass”的类实例的一种方式。所以'String.class.isInstance(x)'是另一种说法'x instanceof String'的方法。 – 2011-04-07 01:09:38

4

这是我的工作是什么。这不是有限产品,而只是测试我是否能够实现它。感谢所有回答问题的人:-)。

public class SimLoader { 
    public static void main(String[] args) 
    { 
    try 
    { 
    Object simulator = Class.forName("SimX").newInstance(); 
    ((SimInterface)simulator).run(); 
    } 
    catch(ClassNotFoundException e) {} 
    catch(InstantiationException e) {} 
    catch(IllegalAccessException e) {} 
    } 
    } 
interface SimInterface { 
void run(); 
} 
class SimX implements SimInterface 
{ 
    public void run() { 
    System.out.println("Success"); 
    } 
} 
+1

最适合我的解决方案。但是不要忘记为Class使用FullyQualifiedName(比如com.mycomapy.SimX,在你的例子中可能不需要)。 – 2015-02-04 14:54:13