【问题标题】:Java loading user-specified classes at runtimeJava 在运行时加载用户指定的类
【发布时间】:2010-05-24 16:09:06
【问题描述】:

我正在使用 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) 用户界面

左侧的机器人类型滚动列表。 中间的“添加>>”和“>”,右侧会出现“AngryRobot1”。)

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

(2) 数据结构的实现

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

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.

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

通过 HashMap 迭代,模拟初始化程序从 Hashmap 中获取项目并实例化适当的机器人。

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

谢谢

【问题讨论】:

    标签: java class runtime


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      如前所述,您可以将 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().equals(actionEvent.getActionCommand()))。然后在您的机器人实例中操作适当的字段。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-11
          • 2013-12-04
          • 2010-12-11
          • 1970-01-01
          • 1970-01-01
          • 2015-05-03
          • 1970-01-01
          相关资源
          最近更新 更多