То, что вы реализовали, является мелкой копией. Для реализации копии deep необходимо
изменить
data[i] = other.data[i];
для некоторой вещи, которая назначает копию из other.data[i]
для data[i]
. Как вы это сделаете, зависит от класса Position
. Возможные альтернативы:
конструктор копирования:
data[i] = new Position(other.data[i]);
заводской метод:
data[i] = createPosition(other.data[i]);
клон:
data[i] = (Position) other.data[i].clone();
Примечания:
- Выше предполагается, что конструктор копирования, метод фабрики и метод клона соответственно реализуют "правильный" вид копирования, в зависимости от класса Position; см. ниже.
- Подход
clone
будет работать только в том случае, если Position
явно его поддерживает, и это обычно рассматривается как неполноценное решение. Кроме того, вы должны знать, что нативная реализация clone
(т.е. метод Object.clone()
) делает поверхностную копию.
На самом деле общая проблема реализации глубокого копирования в Java сложна. В случае класса Position
можно предположить, что все атрибуты представляют собой примитивные типы (например, целые или двойные), и поэтому копирование с глубоким или поверхностным копированием является спорным. Но если есть ссылочные атрибуты, то вам нужно полагаться на конструктор копирования / метод фабрики / метод клона, чтобы выполнить тот тип копирования, который вам необходим. В каждом случае его необходимо запрограммировать. А в общем случае (где вам приходится иметь дело с циклами) это сложно и требует от каждого класса реализации специальных методов.
Существует еще один потенциальный способ копирования массива объектов. Если объекты в массиве serializable , то вы можете скопировать их, используя ObjectOutputStream
и ObjectInputStream
serialize, а затем десериализовать массив. Однако:
- это дорого,
- это работает, только если объекты (транзитивно) сериализуемы, и
- значения любых полей
transient
не будут скопированы.
Копирование с помощью сериализации не рекомендуется. Было бы лучше поддержать клонирование или какой-либо другой метод.
В общем, глубокого копирования лучше избегать в Java.
Наконец, чтобы ответить на ваш вопрос о работах конструктора копирования классов Position
, я ожидаю, что это что-то вроде этого:
public class Position {
private int x;
private int y;
...
public Position(Position other) {
this.x = other.x;
this.y = other.y;
}
...
}
Как говорит @Turtle, в этом нет никакой магии. Вы реализуете конструктор (вручную), который инициализирует его состояние путем копирования из существующего экземпляра.