Java 我可以在知道子类的某些属性值的情况下构建该子类的实例吗

Java 我可以在知道子类的某些属性值的情况下构建该子类的实例吗,java,reflection,Java,Reflection,我有一个所谓的属性类的层次结构,它表示域模型的单个属性。每个属性类都有一个唯一的字符串id属性。 我还有一个AttributeFactory,它有一个基于id检索属性实例的方法 public class Attribute { private String id; private AttributeType type; ....... ....... public Attribute(String id){ this.id=id;

我有一个所谓的属性类的层次结构,它表示域模型的单个属性。每个属性类都有一个唯一的字符串id属性。 我还有一个AttributeFactory,它有一个基于id检索属性实例的方法

public class Attribute {
    private String id;
    private AttributeType type;
    .......
    .......

    public Attribute(String id){
       this.id=id;
    }

    public void setID(String id){
       this.id=id;
    }

    public String getID(){
       return this.id; 
    }

    .......
    .......
}
工厂的界面看起来像

public interface IAttributeFactory {

    Attribute getAttributeByID(String id);
}
例如,该接口的一个实现可以将HashMap作为所有已定义属性的存储库

属性子类的一个示例是:

public class ClientCode extends Attribute {

    public ClientCode(){
        super("clientCode");
        this.setType(AttributeType.CHAR_TYPE);
    }

    ........
    ........
}
问题是,我们是否可以使用反射或任何其他东西来构建属性子类的新实例,而只知道该子类的id,从而实现上面定义的接口,而不需要定义HashMap并将每个新定义的子类添加到HashMap

先谢谢你
Daniel

如果客户机代码任意选择ID,那么就不可能知道哪个ID属于哪个属性子类。然而,如果你能以某种方式强制一个模式,那么是的,只需要知道ID就可以实例化子类。你可以通过反射来实现

下面的示例代码介绍了如何通过反射创建新实例:

public void createInstanceOfSubclass(String id) {
     try {
       Class cls = Class.forName(convertIDToClassName(id));
       Class parameterTypes[] = new Class[1];
       parameterTypes[0] = String.TYPE;
       Constructor ct = cls.getConstructor(parameterTypes);

       Object arglist[] = new Object[1];
       arglist[0] = id;
       Object subclassInstance = ct.newInstance(arglist);
     }
     catch (Throwable e) {
        System.err.println(e);
     }
}
[这只是示例代码;例如,可以在实际实现中改进错误处理。]

基本上,您必须编写convertIDToClassName(String)方法来将ID转换为类名。没有这种联系,就不可能将两者联系起来

另一个想法是属性的ID由您计算;这意味着属性类设置自己的ID字段。因此,可以直接将子类名称和ID字段链接在一起。因此,可以通过ID实例化子类


在任何情况下,个人注释都会避免反射,并坚持在代码中创建类(可能会在工厂类中的某个地方删除实例化代码,以便您的主代码得到引用)。

您需要一个工厂来创建属性的特定子类的实例,对吗?让我们使用典型的工厂模式来实现这一点

//TODO make this a singleton
public final class ClientFactory implements IAttributeFactory {

  public static final String CLIENT_CODE = "clientCode"; //TODO use enum 

  /** This can return a null */
  public final Attribute getAttributeByID(String id) { //TODO rename this getter to something like create
    if (null == id) return null;
    if(id == CLIENT+CODE)
      return new ClientCode(CLIENT_CODE);
    return null;
  }
}

如果你想为每个“属性”都有一个子类,你应该看看java枚举。问题在于,不只是为属性类查找构造函数。我需要实例化相应的子类。因为不仅ID是由子类设置的,我还需要子类的实例,而不是具有相应ID的类的实例。我想我在理解需求方面有点困难。假设只有使用ID,才能找到扩展属性的子类的名称(在您的示例中是“ClientCode”)。上面的代码创建了ClientCode类的一个实例。变量“SubassInstance”引用了ClientCode类。它是子类的一个实例,我认为这就是您想要的。您不必在任何地方静态引用ClientCode,它是在上面的代码中实例化的。请让我了解更多有关需求的信息,以便我能提供更多帮助。很抱歉,我可能无法理解您,因为我的示例中的ClientCode类没有构造函数ClientCode(字符串id)。但无论如何,我同意你的观点,这里的问题是编写convertIDToClassName(id)。顺便提一下,这是我问题的主要关注点,我想知道我是否可以使用反射编写转换,这样我就可以拯救我的工厂