Экземпляр объекта Java, не зная, к какому подклассу он будет принадлежать до времени выполнения

Я не уверен, имеет ли значение эта справочная информация или нет, поэтому я просто опубликую все детали.

Сценарий: у меня есть иерархия подклассов, все они наследуются от одного класса предков. Все суперклассы в иерархии являются абстрактными, поэтому единственными конкретными классами являются классы без подклассов. У меня есть массив:

AncestralClass[] someObjects1 = new AncestralClass[someLength];

AncestralClass - это единственный суперкласс на вершине иерархии, от которого наследуются все другие классы. Этот массив заполнен различными объектами различных конкретных подклассов. Например:

someObjects1[4] = new SubclassObject();

... и так далее; но это произвольно и не имеет значения.

У меня есть второй массив той же точной формы (того же типа, размера и т. Д.), Но второй массив использует первый массив для заполнения себя объектами, снова принадлежащими различным конкретным подклассам. Чтобы быть более точным, тип объекта в элементе во втором массиве будет определяться на основе типа объекта, найденного в том же элементе первого массива. Итак, проблема у меня заключается в следующем: я не буду знать, что содержится в первом массиве, потому что его содержимое генерируется случайным образом во время выполнения, поэтому я не буду знать, каким должно быть содержимое второго массива, так как они зависят от первого массив. Я не уверен, как написать код, который создает новые объекты во втором массиве. Написано на английском, то, что я хочу, звучит так просто и легко. Я хочу перебрать второй массив, проверить соответствующую позицию в первом массиве, проверить, что это за объект, а затем создать экземпляр нового объекта этого типа во втором массиве. Это то, что я не знаю, как кодировать:

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

Вопрос: Чтобы быть более общим, я хочу создать новый объект, который является новым экземпляром класса, к которому принадлежит существующий объект. Как мне это сделать, и я уверен, что есть несколько решений, так что лучше?

Я не знаю много продвинутых вещей в Java, но я думаю, что хорошо разбираюсь в основах. Заранее спасибо.

2 ответа

Из вашего описания видно, что вы заранее знаете множество возможных конкретных классов в первом массиве. Вы можете сделать что-то вроде:

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();
    }
    ....
}

Я думаю, что эта идея является сомнительной. Есть множество проблем, с которыми вы можете столкнуться, пытаясь создать классы типов, которые вы не контролируете заранее.

Поэтому, если бы я это сделал, первым делом я бы использовал простой фабричный метод, который является самым основным творческим паттерном. Таким образом, весь ваш код будет изолирован в одном месте, поэтому, если вам понадобится изменить его позже, вы можете это сделать. Тогда я бы просто использовал отражение для создания объекта.

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, у вас будет удобное место для внесения изменений.

Другие вопросы по тегам