Подтвердить что ты не робот

`* this = rhs` в Java?

Я иду из мира С++, и я не могу найти альтернативу Java (если есть):

struct SomeStruct
{
    SomeStruct(){}
    SomeStruct(const SomeStruct& rhs)
    {
        *this = rhs;
    }
};

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

public class SomeObject
{
    private static Hashtable _objects;
    SomeObject()
    {
        SomeObject obj = _objects.get(some_key);
        if (obj != null) {
            // *this = obj;
            // instead of: 
            // this.something = obj.something;
            // this.something1 = obj.something1;
            // this.something2 = obj.something2;
            // a zillion fields....
        }
    }
};

EDIT:

Извините, я смутил некоторые вещи (по-прежнему нужно изучать как Java, так и С++).

Спасибо

4b9b3361

Ответ 1

Самый близкий Object.clone(), но прочитайте соответствующий раздел из Эффективный Java.

Есть, вероятно, более простые способы сделать то, что вы хотите, если вы устраните некоторые из ваших требований. Например, если вы делаете свои объекты неизменяемыми, вам не нужно копировать данные в другой объект. Вместо этого вы можете вернуть ссылку на исходный объект. Это намного быстрее, чем копирование по порядку, и у него также много других преимуществ, например, упрощение написания потокобезопасного кода.

Ответ 2

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

Ответ 3

public class SomeObject
{
    private static Hashtable _objects;

    public static SomeObject getInstance(SomeKey some_key)
    {
        return _objects.get(some_key);
    }
}

Ответ 4

С вашего вопроса неясно, пытаетесь ли вы достичь чистого кеша неизменных объектов или сохраняете кеш объектов "шаблон" и возвращаете копии, которые затем могут быть изменены клиентом. Я буду считать последнее.

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

public static SomeObject getInstance(...) {
  SomeObject cached = ...;
  if (cached != null) {
    return cached.clone();
  }
  ...
}

Возможно, в вашем конкретном случае вы можете отделить неизменяемые и объекты с сохранением состояния объектов? Если это так, некоторые изменения в вашей объектной модели могут привести к более чистым (и более эффективному) коду?

Ответ 5

В Java, если вы хотите иметь конструктор, соответствующий конструктору копирования, вы должны его реализовать самостоятельно. В некоторых случаях это означает, что вам нужно скопировать поля из одного экземпляра объекта в другой, в то время как в других случаях это означает, что вам нужно реализовать полную глубокую копию - рекурсивно итерации по ссылочным полям параметра в копии ctor.

Это зависит от того, что вы хотите - нужно ли скопировать хэш-таблицу objects? Или оба объекта должны ссылаться на него? Для получения дополнительной информации см. этот вопрос.

Ответ 6

Я не знаю какого-либо общего способа скопировать все содержимое полей с одного объекта на другой, существующий без использования;

  • отражения
  • сгенерированный код.
  • копировать, используя класс Unsafe.

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

Класс Unsafe быстрее, чем отражение, но не перекрестная платформа и небезопасна. Это почти так же быстро, как сгенерированный код.;)

С точки зрения скорости, если сгенерированный код равен 1x, Unsafe - 1,5 - 2x, а отражение - на 2 - 4 раза медленнее для данных с высокой степенью кэширования. Для плохо кэшированных данных вы не увидите разницы.

Ответ 7

Вы должны использовать шаблон Singleton. Вы создаете статический экземпляр SomeObject и работаете с этим экземпляром.

   private static class SingletonHolder { 
     public static final SomeObject INSTANCE = new SomeObject();
   }

   public static SomeObject getInstance() {
     return SingletonHolder.INSTANCE;
   }

Но не попадайте в ловушку Singleton, ограничивайте вызовы getInstance()!