Задать вопрос

Как создать клон объекта в Java?

Нашел такое решение: stackoverflow.com/questions/869033/how-do-i-copy-a...

Оно не подошло. Не знаю как и почему, но все переменные в новом объекте становятся ссылками на переменные старого. Т.е. в нужном месте я создал копию объекта:
MyObject oldObject = new MyObject();
oldObject.someField = 1;
MyObject newObject = new MyObject(oldObject);
oldObject.someField = 2;

и переменная someField у объекта newObject тоже стала равняться 2.

Пробовал написать мегакостыль: в классе, который надо будет копировать, создал функцию clone() и присвоил в ней всем переменным значения из существующего объекта:
public Pot clone() {
        Pot newPot = new Pot();

        Field[] fields = this.getClass().getDeclaredFields();
        for (Field declaredField : fields) {
            try {
                if (declaredField.get(this) == null) {
                    newPot.setValue(declaredField.getName(), null);
                } else {
                    newPot.setValue(declaredField.getName(), declaredField.get(this));
                }
            } catch (IllegalArgumentException | IllegalAccessException ex) {
                Logger.getLogger(PotType.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return newPot;
    }

    public boolean setValue(String key, Object value) {
        try {
            if (!key.equals("initP")) {
                Field declaredField = this.getClass().getField(key);
                declaredField.set(this, value);
            }
        } catch (IllegalArgumentException | IllegalAccessException ex) {
            Logger.getLogger(PotType.class.getName()).log(Level.SEVERE, null, ex);

            return false;
        } catch (NoSuchFieldException | SecurityException ex) {
            Logger.getLogger(PotType.class.getName()).log(Level.SEVERE, null, ex);

            return false;
        }
        return true;
    }


MyObject oldObject = new MyObject();
oldObject.someField = 1;
MyObject newObject = oldObject.clone();
oldObject.someField = 2;

И опять все тоже самое! someField в новом объекте стало равно двум. Что за чертовщина? :) Прошу помощи.
  • Вопрос задан
  • 2016 просмотров
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 2
DR_Demons
@DR_Demons
В Java для клонирования объектов используется интерфейс Cloneable, он Вам не подходит?
example
package my.cloneable;

class User implements Cloneable {
       private String name;
       private int age;
      
       public String getName() {
             return name;
       }
       public void setName(String name) {
             this.name = name;
       }
       public int getAge() {
             return age;
       }
       public void setAge(int age) {
             this.age = age;
       }
      
       public User clone() throws CloneNotSupportedException {
             return (User)super.clone();
       }
}

public class App {

       public static void main(String[] args) {
            
             User user = new User();
            
             user.setName("Иванов");
             user.setAge(25);
            
             System.out.println("Данные до клонирования: " +
user.getName() + " - " + user.getAge() + "лет");
            
             User clone;
             try {
                    clone = user.clone();
                    clone.setName("Петров");
                    clone.setAge(30);
                    System.out.println("Клон после изменения данные: " +
                           clone.getName() + " - " + clone.getAge() + "лет");
                   
             } catch (CloneNotSupportedException e) {
                    System.out.println("Объект не может быть клонированным.");
             }
            
            
             System.out.println("Оригинал, после манипуляций с клоном: " +
 user.getName() + " - " + user.getAge() + "лет");
       }
}
/* результат:
Данные до клонирования: Иванов - 25лет
Клон после изменения данные: Петров - 30лет
Оригинал, после манипуляций с клоном: Иванов - 25лет
 */
Ответ написан
@bobzer
Java EE Developer
У вас 2 варианта:
  1. Использовать какую-либо библиотеку для глубокого клонирования. Плюс в гораздо меньшем количестве бездумного кодинга. Минус в падении производительности и повышенном потреблении ресурсов. Если количество операций клонирования в приложении менее сотни в секунду, то можно не беспокоится по поводу производительности.
  2. Писать всё клонирование самому, поле за полем. Плюс в высокой производительности - ни одна универсальная библиотека не сравнится в скорости с таким подходом. Минус в массе говнокода, который еще и поддерживать надо (при любом изменении класса не забывать дорабатывать методы clone())
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы