在Java中动态加载类

在Java中动态加载类,java,dynamic,Java,Dynamic,我查阅了语法并搜索了api,但仍然对过程感到困惑。我还搜索了Stackoverflow。加载类并从中动态创建对象的正确方法是什么?换句话说,我希望用户指定要创建的对象类型,然后创建该类型的对象。我不需要菜单,因为我希望他们能够选择当前目录中的任何类。将加载一个类。您通过myClass.getClassLoader()获得一个类加载器,如果该值为空,您应该返回到classloader.getSystemClassLoader() 一旦你有了一个类实例,你就可以通过。 因此,如果您有一个带有构造函数

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

将加载一个类。您通过
myClass.getClassLoader()
获得一个类加载器,如果该值为空,您应该返回到
classloader.getSystemClassLoader()

一旦你有了一个类实例,你就可以通过。 因此,如果您有一个带有构造函数的
公共类MyClass
,比如
公共MyClass(String){…}
,那么

Class<MyClass> clazz = MyClass.class;
Constructor<MyClass> ctor = clazz.getDeclaredConstructor(String.class);
MyClass instance = ctor.newInstance("foo");
Class clazz=MyClass.Class;
构造函数ctor=clazz.getDeclaredConstructor(String.class);
MyClass实例=ctor.newInstance(“foo”);

上面忽略了一系列可能的异常。

假设该类没有arg构造函数,最简单的方法是-

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

参考-

以下是我的工作内容。这不是一个完善的产品,但只是测试,看看我是否可以得到它的工作。感谢所有回答问题的人:-)


您是想从binary.class文件加载类还是按类名加载类?@JustinWaugh Hi Justin,公认的答案适合加载.class文件吗?如果它有arg,该怎么办?如何调用类上的方法?如何仅按类的名称强制转换newObject?当我尝试在类型对象上调用类的方法时,它告诉我对象的方法未定义。如果在编译时不知道类的类型,则必须使用反射来查找和调用方法。如果构造函数有一个参数,您可以对从
class.forName
返回的类使用
getDeclaredConstructor()
,如Mike Samuel+1给Justin的答案所示。而且,实际上,你不可能对这个类一无所知,因为那样的话,实际使用它将非常困难。让这些未知类实现一个特定的接口通常是一个好策略。然后,您可以通过接口引用这些对象,以便对它们调用方法等。类的完全限定类名是什么?您不应该使用
.newInstance()
。如果零参数构造函数抛出选中的异常,
.newInstance()
将这些异常作为运行时异常进行清洗,因此您将失去异常安全性。从javadoc中可以看出:“使用此方法可以有效地绕过编译器执行的编译时异常检查。”MyClass是对该类的实例还是静态引用?有没有办法通过将类的名称作为字符串传递给方法来获取类的构造函数?或者与此类似的任何方式?
MyClass
是本例中类的名称。一个类可以有多个构造函数(接口可以没有);类没有“构造函数”。
MyClass.class
可能会混淆语法。这只是引用
MyClass
的类实例的一种方式。因此
String.class.isInstance(x)
是表示
x instanceof String
的另一种方式。如何创建实例而不实际硬编码类名?我想通过向函数传递字符串来加载该类,它构造并实例化该类的对象。@rubixibuc,
class clazz=myClassLoader.loadClass(className)
,如第一段所述。这是我的最佳解决方案。但不要忘记对类使用FullyQualifiedName(比如com.mycomapy.SimX,在您的示例中可能不需要)。
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");  
  }  
}