是否可以动态加载类并将其用作类型?

时间:2016-04-01 14:24:42

标签: java classloader instantiation

我正在尝试创建一个动态加载类的代码,并使用它来创建新实例并运行强制转换。我可以使用此方法从新加载的类中创建一个实例:myClass.newInstance();。但我不能用它作为一种类型。例如:myClass myObj = new myClass();它不起作用。有可能以某种方式执行吗?

这是我试图制作的代码:

URL classUrl;
classUrl = new URL("file:///C:/classes/");
URL[] classUrls = { classUrl };
URLClassLoader ucl = new URLClassLoader(classUrls);
Class c = ucl.loadClass("Operation");
Class MyIn = ucl.loadClass("MyInter"); 
Object o = c.newInstance(); //IT WORKS
System.out.println(((MyIn) o).sum(2, 4)); //IT DOES NOT WORK. Message: MyIn cannot be resolved to a type

2 个答案:

答案 0 :(得分:5)

由于您在编译时不知道MyIn,因此您不仅需要使用反射来实例化类,还需要调用方法。

有些事情:

MyIn.getDeclaredMethod("sum",Integer.TYPE,Integer.TYPE).invoke(o,2,4);

参见例如https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html

答案 1 :(得分:1)

您无法在编译时直接使用在运行时加载的类。

但是,您可以直接通过加载的类实现的一个或多个 接口 工作。通常,接口本身包含在加载代码和加载代码的编译时类路径中。

共享接口在编译时定义预期的交互。加载的代码定义运行时的行为。

例如,您可以加载此动态加载的类:

public class Operation implements MyInterface { ... }

然后通过共享界面与它进行交互:

Class c = ucl.loadClass("mypackage.Operation");
Object o = c.newInstance(); //IT WORKS
MyInterface operation = (MyInterface) o;

现在,您可以通过共享界面直接与方法进行交互。

System.out.println( operation.sum(2, 4) );

<强>构造

  

例如:myClass myObj = new myClass();它不起作用。有可能以某种方式表演吗?

您可以在动态加载的代码中创建一个带有命名构造函数的工厂。工厂还将实现共享接口。

Class cFactory = ucl.loadClass("mypackage.MyFactory");
MyFactoryInterface factory = (MyFactoryInterface) cFactory.newInstance();     
MyInterface myObj = factory.makeOperation( );