2016-10-29 9 views
1

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

public Validation copy(Validation newValidation){return newValidation;} 

так, если реализована следующим образом:

Validation x = new Validation(); 
Validation y = x.copy(x); 

и убедитесь, что у есть все методы/переменные х и что при работе с переменными в у, не влияют на переменные в x. У меня есть ощущение, что я хочу, это метод «глубокой копии», и я нашел сообщение об этом здесь: Creating a deep copy method, Java, но у этого человека нет аргументов для их метода, поэтому я не знаю, как он на самом деле копируется.

+0

Нужна ли вам глубокая копия или нет, все зависит от кода внутри класса Vlidation, можете ли вы предоставить код подтверждения? – developer

+0

Пример в ссылке создает копию текущего объекта ('this'). – infiniteRefactor

+0

Возможный дубликат [Clone() vs Copy constructor - который рекомендуется в java] (http://stackoverflow.com/q/2427883/5221149). – Andreas

ответ

1

Да, он ничего не делает, кроме возвращения той же ссылки, которая была передана.

Возможно, вы ищете метод Object#clone() *:

public Validation copy(Validation newValidation) { 
    return newValidation.clone(); 
} 

В 95% случаев, что является наиболее подходящим и правильным решением для различных типов задач. Вы не должны изобретать велосипед, если это не нужно.

В документации Java говорит:

... этот метод выполняет "неполную копию" этого объекта, а не "глубокая копия" операции.

... может потребоваться изменить одно или несколько полей объекта, возвращенного super.clone, перед его возвратом.

Validation y = x.copy(x); 

Вы не должны пройти x к copy метод, потому что, когда вы вызываете этот метод на x, например, в классе у вас есть доступ к this, который в данном случае представляет ваш x ,

Validation y = x.clone(); 

Для "мелкой копией" предыдущий пример хорош, но для "глубокой копии" вам необходимо изменить поведение по умолчанию Object#clone():

class A implements Cloneable { 

    public @Override A clone() throws CloneNotSupportedException { 
     return (A)super.clone(); // or or another implementation 
    } 

} 

class Validation implements Cloneable { 

    // an example of a reference-type field 
    private A a; // with a setter 

    public @Override Validation clone() throws CloneNotSupportedException { 
     Validation newClone = new Validation(); 

     // note that the `A` class has to implement the `Cloneable` 
     // and override the `clone` method making it `public` 
     newClone.setA(this.a.clone()); 

     return newClone; 
    } 

} 

* Не забудьте реализовать интерфейс Cloneable, чтобы разрешить клонирование.

Для чтения: Effective Java, Item 11: Override clone judiciously.

+0

Ну ладно, так что это приведет к дублированию объекта, но переменные которого имеют разные ссылки, чем первый объект? – Redcoatwright

+0

@Redcoatwright, Нет, ссылки на поле экземпляра будут такими же, как у исходного объекта – Andrew

+0

@Redcoatwright, я обновил – Andrew

0

Java-API имеет Cloneable интерфейс. Object имеет метод клонирования, доступ к которому возможен только тогда, когда он переопределяется в подклассе, который также реализует интерфейс Cloneable. Ваш метод действительно не создает копию, так как «копия» указывает на исходный экземпляр.

Скажем, я сделать копию Validation:

Validation v = new Validation(); 
v.setId(1); 
Validation valid = v.copy(v); 
valid.setId(2); 

Теперь идентификатор в V будет меняться, как хорошо, потому что valid указывает на v.

Но clone -Метод делает глубокую копию. Вот небольшой пример:

public class Product { 

private int id; 
private String name; 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

@Override 
public String toString() { 
    return "Product{" + "id=" + id + ", name=" + name + '}'; 
} 

@Override 
protected Object clone() throws CloneNotSupportedException { 
    Product p = new Product(); 
    p.setId(id); 
    p.setName(name); 
    return p; 
} 

} 

public static void main(String[] args) { 
    Product p = new Product(); 
    try { 
     Product clone = (Product) p.clone(); 
     System.out.println(clone.toString()); 
    } catch (CloneNotSupportedException ex) { 
     Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
+0

Извините, это может быть немного по моей голове. Что делают «броски»? – Redcoatwright

+1

Существует плохой пример, понимаете ли вы, что клонированный экземпляр будет иметь те же ссылки экземпляров, что и исходное? Для примитивного поля 'int' это не имеет значения, как и для' String' из-за пула 'String'. Итак, в этом случае стандартный '' '' '' '' '' '' '' 'объекта имеет такое же поведение с некоторыми оптимизациями. – Andrew

+0

@Redcoatwright, 'CloneNotSupportedException' является проверенным исключением, которое будет выбрано, если ваш класс не предоставляет клонирование (не реализует интерфейс' Cloneable') – Andrew