Ответ 1
То, что вы внедрили, - это мелкая копия. Чтобы выполнить копию глубокой, вы должны изменение
data[i] = other.data[i];
к чему-то, что присваивает копию от other.data[i]
до data[i]
. Как вы это делаете, это зависит от класса Position
. Возможные альтернативы:
-
конструктор копирования:
data[i] = new Position(other.data[i]);
-
a factory метод:
data[i] = createPosition(other.data[i]);
-
клон:
data[i] = (Position) other.data[i].clone();
Примечания:
- Вышеизложенное предполагает, что конструктор копирования, метод factory и метод клона соответственно реализуют "правильный" вид копирования, в зависимости от класса Position; см. ниже.
- Подход
clone
будет работать, только еслиPosition
явно поддерживает его, и это обычно рассматривается как низшее решение. Кроме того, вам нужно знать, что встроенная реализацияclone
(т.е. МетодObject.clone()
) выполняет мелкую копию.
На самом деле общая проблема реализации глубокого копирования в Java сложна. В случае класса Position
можно предположить, что атрибуты являются всеми примитивными типами (например, ints или double), и поэтому глубокое или мелкое копирование является спорным. Но если есть ссылочные атрибуты, тогда вам нужно полагаться на метод-конструктор копирования /factory метод/клон, чтобы выполнить требуемый тип копирования. В каждом случае его необходимо запрограммировать. И в общем случае (где вам приходится иметь дело с циклами) это сложно и требует, чтобы каждый класс применял специальные методы.
Существует еще один возможный способ копирования массива объектов. Если объекты в массиве сериализуемы, вы можете их скопировать, используя ObjectOutputStream
и ObjectInputStream
сериализовать, а затем десериализовать массив. Однако:
- Это дорого,
- он работает только в том случае, если объекты (транзитно) сериализуемы и
- значения любых полей
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, там нет волшебства. Вы реализуете конструктор (вручную), который инициализирует его состояние, копируя из существующего экземпляра.