java实例化对象,不知道它将属于哪个子类,直到运行时

时间:2014-11-11 18:07:37

标签: java objectinstantiation

情境:    我有一个子类的层次结构,所有子类都继承自单个距离的祖先类。层次结构中的所有超类都是抽象的,因此唯一具体的类是没有子类的类。我有一个数组:

AncestralClass[] someObjects1 = new AncestralClass[someLength];

ancestralClass是层次结构顶部的单个超类,所有其他类都继承自该类。   该数组填充了各种具体子类的不同对象。例如:

someObjects1[4] = new SubclassObject();

......等等。

我有一个完全相同形式的第二个数组(相同的类型,大小等),但是第二个数组使用第一个数组来填充自己再次属于各种具体子类的对象。更具体地说,第二个数组中元素中的对象类型将根据在第一个数组的同一元素中找到的对象类型来决定。所以我遇到的问题是:我不知道第一个数组中包含什么,因为它的内容是在运行时随机生成的,因此我不知道第二个数组的内容应该是什么,因为它们依赖于第一个数组阵列。我不知道如何编写实例化第二个数组中的新对象的代码。用英文写的,我想要发生的事情听起来如此简单和容易。我想遍历第二个数组,检查第一个数组中的相应位置,检查是什么类型的对象,然后在第二个数组中实例化该类型的新对象。那就是我不知道如何编码:

someObjects2[i] = new (subclass that someObjects1[i] belongs to)(); 

问题 更一般地说,我想实例化一个新对象,它是现有对象所属的类的新实例。我该怎么做,我确定有多种解决方案,哪个更好?

2 个答案:

答案 0 :(得分:0)

从您的描述中可以看出,您事先知道第一个数组中可能的具体类的集合。你可以这样做:

for (int i = 0; i < array1.length; i++) {
    if (array1[i] instanceof SubclassObject1) {
        array2[i] = new SubclassObject1();
    } else if (array1[i] instanceof SubclassObject2) {
        array2[i] = new SubclassObject2();
    }
    ....
}

答案 1 :(得分:0)

我认为这个想法有点可疑。你可以尝试创建各种类型的问题,这些问题可以提前完成。

所以,如果我这样做,我要做的第一件事就是使用一个简单的工厂方法,这是最基本的创作模式。这样,您可以将所有代码隔离在一个位置,因此如果您以后需要更改它,则可以。然后我会用反射来创建对象。

public class Creation
{
   private Creation() {}

   public static <S, T extends S> S makeNew( T obj )
           throws InstantiationException, IllegalAccessException
   {
      return (S) ( obj.getClass().newInstance() );
   }

   // Demonstration
   public static void main( String[] args )
           throws InstantiationException, IllegalAccessException
   {
      CharSequence[] cs = { new StringBuilder(), new Segment()  };
      for( CharSequence c : cs ) System.out.println( makeNew( c ) );
   }
}

这适用于简单的情况。如果您将来需要使用像Objenesis这样的花哨库,您可以轻松地进行更改。