Почему нет простого способа скопировать объекты в Java? - PullRequest
1 голос
/ 11 августа 2011

У меня есть класс TimeLine в моем графическом интерфейсе. У меня есть функция, в которой я хотел бы скопировать эту временную шкалу и изменить данные в ней, не затрагивая при этом TImeLine в моем графическом интерфейсе.

Я искал на некоторых форумах и не нашел простого пути, потому что Java давала ссылки. Почему нет простого способа создать новый объект (временную шкалу), который не имеет ссылки на предыдущий?

Помогите, пожалуйста, сделать копию этого объекта TimeLine!

Ответы [ 5 ]

4 голосов
/ 11 августа 2011

Метод clone() и интерфейс Cloneable, предложенные другими авторами, были созданы с неверным предположением, что было бы неплохо иметь общее копированиеметод.Реализации по умолчанию делают мелкий клон текущего объекта, но вы можете переопределить его, чтобы сделать глубокий клон.

Не существует правильного, общего способа копирования произвольных объектов, то, что вы хотите скопировать, зависит от задействованных объектов.Например, неизменяемые объекты никогда не нуждаются в копировании (это было бы просто пустой тратой пространства), в то время как некоторые типы объектов не могут быть скопированы (как бы вы скопировали FileOutputStream, например?),

Самый элегантный способ, который я нахожу, - это неизменяемые объекты с методами, которые возвращают копию только с одним измененным полем:

class Pony {
    private final String name;
    private final Color color;
    private final int tailLength;

    // constructors and accessors omitted

    Pony withName(String newName) {
        return new Pony(newName, color, tailLength);
    }

    Pony withColor(Color newColor) {
        return new Pony(name, newColor, tailLength);
    }

    Pony withTailLength(String newTailLength) {
        return new Pony(name, color, newTailLength);
    }
}

// Usage:

Pony tony = new Pony("Tony", Color.DAPPLE, 32);
Pony maurice = tony.withName("Maurice") // Maurice is like Tony, but black.
                   .withColor(Color.BLACK);

К сожалению, вы получаете множество шаблонов таким образом, и нетподдержка основной IDE либо (возможно, есть плагины).С этим связан шаблон Builder , рекомендованный Джошем Блохом в Effective Java.

3 голосов
/ 11 августа 2011

Вместо clone() вы можете подумать о написании конструктора копирования для вашего класса:

public TimeLine(TimeLine original) {
    this.foo = original.foo;
    this.bar = original.bar;
}

Будьте осторожны при копировании значения любых ссылочных полей в вашем классе. Обязательно, хотите ли вы мелкую копию или глубокую копию.

2 голосов
/ 11 августа 2011

В Java с помощью оператора "=" вы просто копируете ссылки на объекты.Если вы хотите реализовать копирование по значению, используйте операцию clone (метод clone () класса Object) или реализуйте свой собственный метод clone (переопределяя реализованный).

Обратите внимание, что если ваш класс хранит другой объект внутриэто, эти объекты должны в конечном итоге тоже клонировать (ГЛУБОКАЯ КОПИЯ).

1 голос
/ 11 августа 2011

Вы ищете метод clone.(Я ходил туда-сюда по поводу того, какую документацию цитировать, это Википедия, ее обработка более тщательная. Конечно, Java doc более официальный).

Например,

MyObject a = new MyObject();
a.setSomething( 2 );
MyObject b = a.clone();

// now b.getSomething().equals(a.getSomething()) (maybe == too, depends on class)
// and b.equals(a)
// b != a
1 голос
/ 11 августа 2011

, если вы хотите скопировать объект, используйте clone()

если я неправильно понял ваш вопрос, пожалуйста, прокомментируйте

...