Это лучший способ заменить объект Java? - PullRequest
1 голос
/ 04 декабря 2011

Иногда я хочу «заменить» объект другим объектом того же класса.Обычно я делаю это следующим образом.

Класс объекта с конструктором:

public class Type {

    private int field;
    private double anotherField;

    public Type(Type anotherTypeInstance) {
        this.field = anotherTypeInstance.getField();
        this.anotherField=anotherTypeInstance.getAnotherField();
    }
}

Поэтому, когда я хочу заменить объект, я просто делаю это

Type oldInstance = new Type(newInstance)

Иногда это легко и удобно сделать, а другим нет.Есть ли альтернатива?

EDIT:

Мне нужна такая «замена» в алгоритмах оптимизации.Где я должен заменить текущее Решение (объект) другим Решением, которое имеет меньшую стоимость

Ответы [ 3 ]

1 голос
/ 04 декабря 2011

Да, это нормально.Лучший способ был бы:

public class Type {
    private int field;
    private double anotherField;

    @Override
    public Object clone() {
        Type anotherTypeInstance = new Type();
        anotherTypeInstance.field = field;
        anotherTypeInstance.anotherField=anotherField;
        return anotherTypeInstance;
    }
}
// Usage
Type object1 = new Type();
Type object1Cpy = (Type) object1.clone();
1 голос
/ 04 декабря 2011

Вы можете реализовать интерфейс Cloneable и метод clone() следующим образом

@Override
public Type clone() {
  try {
    return (Type) super.clone();
  } catch (CloneNotSupporedException cnse) {
    throw new RuntimeException(cnse); // Never happens.
  }
}

Если вы используете clone() для более сложных классовВам необходимо убедиться, что все изменяемые объекты, на которые ссылаются поля класса, также рекурсивно клонируются, то есть, что вы делаете глубокую копию вместо мелкой копии.Случайное совместное использование состояния, которое может произойти в результате мелкого копирования, может привести к проблемам, которые трудно отладить.

Использование clone() имеет ряд проблем.Он обходит конструкторы, которые обычно являются местом, где применяются начальные инварианты класса.Это очень подвержено ошибкам для классов, содержащих больше, чем просто примитивные типы.Кроме того, использование clone() несовместимо с не примитивными конечными полями, поскольку вы не можете исправить их после клонирования объекта в случае, если они требуют модификации для обеспечения глубокого копирования.

Рассмотрим, например, этот класс:

public class Car {
  private final Engine engine;

  // ... 

  @Override
  public Car clone() {
    try {
      Type copy = (Type) super.clone();
      copy.engine = (Engine) engine.clone(); // Error: final field cannot be modified.
      return copy;
    } catch (CloneNotSupportedException cnse) {
      throw new RuntimeException(cnse);
    }
  }
}

Копировать конструкторы, подобные тому, который был опубликован в вопросе, гораздо лучше.

0 голосов
/ 04 декабря 2011

Вы можете использовать Object.clone(), который является стандартным способом создания копии существующего объекта.

Однако я не могу вспомнить, когда в последний раз мне приходилось использовать clone().Зачем вам нужна копия существующего объекта с точно такими же полями?Вы хотите внести изменения в объект, не затрагивая «оригинальный»?Рассмотрите возможность использования неизменяемых объектов.

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