Java在运行时加载用户指定的类

时间:2010-05-24 16:09:06

标签: java class runtime

我正在研究Java中的机器人模拟(Swing应用程序)。我有一个抽象类“机器人”,从中衍生出不同类型的机器人,例如

public class StupidRobot extends Robot {
   int m_stupidness;
   int m_insanityLevel;
   ...
}

public class AngryRobot extends Robot {
   float m_aggression;
   ...
}

如您所见,每个Robot子类都有一组不同的参数。

我想要做的是在初始UI中控制模拟设置。选择机器人的数量和类型,给它起一个名字,填写参数等。

这是一个像恐龙程序员,Java新手的时代之一,我想知道是否有一些更高级别的东西/想法可以帮助我。所以这就是我所拥有的:

(1)用户界面

滚动左侧机器人类型列表。 “添加>>”和中间的“<<< Remove”按钮。 默认命名的右侧机器人滚动列表。 下方的“设置参数”按钮。 (所以如果你想要一个AngryRobot,你可以在左侧列表中选择AngryRobot,点击“添加>>”并在右侧显示“AngryRobot1”。)

在右侧选择机器人时,单击“设置参数...”按钮,这将调用另一个模型对话框,您可以在其中填写参数。每个都需要不同的对话框 机器人类型。

(2)数据结构实现

作为最终产品,我认为HashMap最方便。键是Robot类型,伴随的对象是所有参数。初始化程序可以只检索每个项目一次和实例化。这是数据结构的样子:

enum ROBOT_TYPE {STUPID, ANGRY, etc}

public class RobotInitializer {
    public ROBOT_TYPE m_type;
    public string m_name;
    public int[] m_int_params;
    public float[] m_float_params;
    etc.

初始化程序的构造函数将根据类型

创建适当的长度参数数组
public RobotInitializer(ROBOT_TYPE type, int[] int_array, float[] float_array, etc){
     switch (type){
        case STUPID:
            m_int_params = new int[STUPID_INT_PARAM_LENGTH];
            System.arraycopy(int_array,0,m_int_params,0,STUPID_INT_PARAM_LENGTH);

        etc.

一旦实例化了所有RobotInitializer,它们就会被添加到HashMap中。

通过HashMap迭代,模拟初始值设定项从Hashmap中获取项目并实例化相应的机器人。

这合理吗?如果没有,怎么改进?

由于

3 个答案:

答案 0 :(得分:3)

您可以使用反射在运行时动态加载类型。请参阅Class.forName,了解如何获得Class的完全限定名称。然后,您可以使用isAssignableFrom方法检查该类是否为Robot的子类。您可以在Robot中定义一些模板方法,让子类指定具体行为(例如,应该初始化哪些属性)。一旦获得了类定义,就可以使用newInstance()方法创建Robot的实例(该类必须有一个默认的构造函数,否则你应该使用getConstructors()方法并使用你的那个要)。

我知道在给定类文件的完整路径的情况下,还有另一种加载类定义的方法,但现在还不记得。

答案 1 :(得分:1)

您也可以使用RMIClassLoader,但如果您可以这样使用它,我会建议使用Fede的响应。

答案 2 :(得分:1)

如上所述,您可以使Robot成为RobotInterface的实现。然后:

Class aRobotClass = Class.forName("robotClassName"); //or similar
Class[] aRobotClassImplements = aRobotClass.getIterfaces();
// Then ensure that "RobotInterface" exists in the aRobotClassImplements array.

RobotInterface应该为Robot属性定义getter和setter。

我认为eash机器人可以有一系列不同的属性。可以动态检查Robot实例并创建适当的按钮/控制器。例如:

Field[] robotFields = aRobotClass.getFields();

for (Field field : robotFields) {
   JButton jbutton = new JButton(field.getName());
   //assuming this class implements ActionListener
   jbutton.addActionListener(this);
   // Then assume we have a private class representing a button )
   this.hashMapOrVectorOfButtons.add(new PrivateButton(field));
   jpanel.add(jbutton);
   // etc etc
}

稍后在actionPerformed中,循环遍历注册按钮的hashmap或向量。 (field.getName()。等于(actionEvent.getActionCommand()))。然后操纵Robot实例中的相应字段。