2013-10-07 59 views
5

我只有大约半年的Java经验,所以请原谅我缺乏知识。我试着做一些谷歌搜索,我对此有一些想法,只有几个漏洞需要填写。Java动态工厂

我正在尝试为我正在执行的程序创建一个“动态工厂”。这样做的基础是我希望人们能够将类文件插入到文件夹中,然后将它们加载到我的工厂中,以便稍后创建它们的新实例。

这就是我现在所拥有的:

import java.util.HashMap; 
import java.util.Map; 

public class KitManager { 

    private Map<String, Class<? extends Kit>> kitMap; 

    public KitManager() { 
     kitMap = new HashMap<String, Class<? extends Kit>>(); 
    } 

    public Kit makeKit(String kitname) { 
     try { 
      return kitMap.get(kitname).newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 
} 

现在什么,我试图找出是如何让所有的类文件夹内,确保它们延伸套件,然后将其插入放入地图中以便稍后创建它们的实例。这是我卡住的地方,我想不出有什么好的方法让类加载到地图中,而不需要在配置文件中找到类名和查找字符串。我的想法是在每个类中都有静态代码,将自己插入到HashMap中,但我不确定这是如何工作的。我真正要求的是一个关于如何去完成我的目标的想法。 (有一个用户可以输入类的文件夹(扩展Kit),然后当我的程序被加载时,这些类会动态加载到我的kitMap中)

回答

2

当需求有点模糊时,很难给出一个好的答案。

从你说的话,你可以只创建一个指向,用户把自己的类目录中的类加载器:

ClassLoader kitClassLoader = new URLClassLoader("file://<path>", KitManager.class.getClassLoader()); 

要真正找到类,使用简单的目录列表的方法,例如java.io.File.listFiles()(使用指向正确的路径显然是一个文件实例):

File[] candidates = new File("<path>").listFiles(); 

然后,您可以使用kitClassLoader实际加载发现了一类:

kitClassLoader.loadClass(className); 

类名称可以通过简单地将listFiles()中找到的文件中的“.class”扩展名分解而得到。在加载完类之后,你可以检查它是否有一个默认的构造函数,并且如果它确实实现了Kit(如果没有,拒绝它或者显示错误信息)。

这就是基本的方法,但是它有严重的安全问题(你不知道什么类实际上将当你加载它们),也可能引入具有相关性的问题(您加载可能需要额外的类库?)。

+0

类加载器的目的究竟是什么?编辑:所以显然评论不喜欢里面的代码。难道我不能像file.getClass()。asSubclass(Kit.class)那样做,并将其添加到hashmap中(假设一切安装正确,文件扩展工具包等等) – Phiction

+0

@ user2792581 * *只有通过ClassLoader才能获得虚拟机的类。问题是File.getClass()根本不存在。 ClassLoader是从虚拟机中的类文件到实际类的桥梁。 – Durandal

+0

我假设kitClassLoader.classForName(className);是指kitClassLoader.loadClass()? – Phiction