动态Java程序的DLL?

Myn*_*Myn 3 java dll

我目前正在开发一个Java项目,我有一组数据,我希望以多种自定义格式输出.我为每种格式都有一个类,它接收原始数据并相应地转换它.但是,首先,我只实现了这些格式中的两种或三种,但希望允许在以后添加更多格式,而无需对应用程序进行大规模重建.

我的想法是为每个格式类创建一个DLL,并让我的应用程序传递数据以转换为每个格式.这样,我可以稍后创建一个DLL并让我的主应用程序访问它.(我很乐意听谁已经在C++/C#这样做过这种感觉就像合理的解决方案这样做,有人的任何替代方法,但它可能并不适用于Java的)

我的问题是我完全不知道如何做到这一点 - 在C++/C#中我可以用几行代码编写它,但我不确定它如何与Java一起工作.有可能提出一个非常模糊的问题,我该怎么做?

非常感谢答案,并提供饼干和茶.:)

先谢谢,M

编辑:对不起,只是添加:我也不确定如何创建DLL,这个项目必须是Java,才能首先阅读.谢谢.:)

coo*_*ird 5

而不是使用DLL本身,似乎所需要的是某种插件架构.

除非有必要,否则我不建议使用DLL的一个原因是将Java代码与本机代码链接将需要使用Java本机接口(JNI),这可能需要比纯Java解决方案更多的努力.

一种相对简单的方法是使用Java 的反射功能.

根据给出的信息,我可能会按照以下方式进行:

  1. 定义输出格式的接口.
  2. 创建实现该接口的Java类.
  3. 类路径中获取.
  4. 使用反射动态加载类.(使用该Class.newInstance方法可以从classClassLoader.加载的文件中实例化对象.)

通过这些步骤,可以实现一个简单的插件,当需要支持新格式时,该插件不需要完全重建.


第1步:定义界面

假设我们最终得到如下界面:

public interface Outputter {
  public void write(Data d);
}
Run Code Online (Sandbox Code Playgroud)

第2步:创建一个实现类

然后,我们将创建一个实现类.

public class TextOutputter {
  public void write(Data d) {
    // ... output data to text
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,编译上面的内容,我们最终得到一个class名为的文件TextOutputter.class.

第3步:从类路径中使类可用

运行主应用程序时,我们需要TextOutputter.class类路径中具有上述内容.通常,可以告诉JVM一个要考虑作为类路径的位置列表,并且应该包括上面的class文件.

一旦完成,我们应该能够使用反射加载上面的类.

第4步:使用反射动态加载类

现在,当我们真正想加载上面的类时,我们会做类似以下的事情:

// Note: We load the class by specifying the fully-qualified class name!
Class<?> clazz = Class.forName("TextOutputter");

// Then, we instantiate the class.
// Note that the following method will call the no-argument constructor.
Outputter outputter = clazz.newInstance();      

// Now, we can give data to the TextOutputter object that we loaded dynamically.
outputter.write(...);
Run Code Online (Sandbox Code Playgroud)

Class.forName方法用于尝试TextOutputter从默认值中查找类ClassLoader.一旦我们获得该类作为Class表示,我们就可以实例化该类的对象.

可以使用该Class.newInstance方法来实现对象的实例化.如果应该使用除无参数构造函数之外的其他东西,则Constructor必须获取类的类,然后从那里实例化对象.

然后通过反射实例化的对象被放入一个Outputter变量中,因此write可以在该方法上调用该方法TextOutputter.

添加更多格式将需要上述过程,但是更改完全限定的类名(例如String,对于FQCN java.lang.String)是加载不同类所需的全部内容.


简而言之,这就是动态加载class文件并从应用程序中使用它所需要的.

(正如旁注,我实际上并没有编译上面的代码,所以这里和那里可能会有一些错误,但我希望我能说明它将采取的过程.)