0

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

AncestralClass[] someObjects1 = new AncestralClass[someLength];

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

someObjects1[4] = new SubclassObject();

... 等等。

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

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

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

4

2 回答 2

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这样的精美库,您可以轻松地进行更改。

于 2014-11-11T18:31:04.633 回答
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();
    }
    ....
}
于 2014-11-11T18:21:10.673 回答