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