WedX - журнал о программировании и компьютерных науках

Почему мы реализуем Cloneable, даже если мы можем пойти на глубокое клонирование, используя следующий фрагмент

public class Color {
 String color;
 Color(String color)
 {
   this.color=color;         
 }
 }


public class ColoredCircle {
int x;
Color color;
ColoredCircle(int x, Color color)
{
    this.x=x;
    this.color=color;
}
public Object testClone()
{
    Color c = new Color(this.color.color);
    ColoredCircle cc1 = new ColoredCircle(this.x, c);
    return cc1;
}
}

В упомянутом выше классе ColoredCircle у нас есть метод с именем testClone(), и он работает точно так же, как глубокое клонирование. Теперь я запутался в том, что нужно реализовать Cloneable для клонирования? И является ли вышеуказанная программа разновидностью глубокого клонирования?


  • На самом деле, в наши дни считается очень плохим использовать Cloneable и реализовывать clone. 14.10.2015
  • Потому что поверхностная копия требует меньше памяти, чем глубокая. 14.10.2015
  • @RealSkeptic, надеюсь, нет необходимости внедрять Cloneable для глубокого клонирования? 14.10.2015
  • вы можете программно клонировать объекты, но как насчет массивов? 14.10.2015
  • @ArijitDasgupta Я не получил ваш последний вопрос RealSkeptic. Вы можете реализовать глубокую копию в методе sljgfsaja. Это сделает работу, но не реализует интерфейс Clonable. Ваши клиенты просто должны знать, что они должны использовать этот метод. Никакая международная группа правоохранительных органов Java не пинает вашу дверь, если вы не используете интерфейс ... Может быть, я просто неправильно понял вопрос. 14.10.2015
  • @Fildor Спасибо за объяснение. Объяснение и юмор дали мне некоторое облегчение !!! 14.10.2015
  • Важно знать: о возможности клонирования Java. 14.10.2015
  • @RealSkeptic, когда я занимаюсь глубоким клонированием, обычно не использую метод .clone(). Я вручную реализую логику. Из-за этого он не выдает CloneNotSupportedException, поскольку я не реализую интерфейс Cloneable. Итак, мой вопрос: действительно ли необходимо реализовывать интерфейс, когда он технически не работает? 14.10.2015
  • Неважно, занимаетесь ли вы глубоким или поверхностным клонированием. Если вы не используете clone, вы не должны реализовывать Cloneable. А так как вообще не рекомендуется реализовывать Cloneable и clone, предполагается, что вы будете выполнять глубокое копирование другими способами. 14.10.2015

Ответы:


1

Нужно ли внедрять Cloneable для клонирования? Да. Метод clone() имеет модификатор защищенного доступа со следующим пояснением Javadoc: -

Этот метод создает новый экземпляр класса этого объекта и инициализирует все его поля точно содержимым соответствующих полей этого объекта, как бы по присваиванию; содержимое полей само по себе не клонируется. Таким образом, этот метод выполняет shallow copy операции с этим объектом, а не deep copy операции.

Ваш метод testClone хотя и может быть правильным в поведении клонирования, но сам по себе не является клонируемым объектом. Клонируемый объект должен реализовывать Cloneable интерфейс и предпочтительно иметь общий доступ для clone(), чтобы его можно было использовать вне класса.

Чему-то, кто читает ваш курс, будет трудно понять важность метода testClone().

14.10.2015
  • Зависит от того, что вы подразумеваете под клоном. Нужно ли реализовывать Cloneable для использования метода clone() в соответствии с его контрактом? Да. Это необходимо для того, чтобы вообще клонировать (сделать копию) объекта? Нет. Конструктор копирования или что-то подобное гораздо предпочтительнее. 14.10.2015

  • 2

    Реализация интерфейса Cloneable нужна для того, чтобы вызов Object.clone() не вызывал исключение. (В этом вся цель Cloneable.)

    Вы не используете Object.clone(). Таким образом, реализация Cloneable или нет не имеет значения. Это не имеет ничего общего с тем, как называется ваш метод. Ваш метод может называться testClone(), и он может вызывать до super.clone(). Или ваш метод может называться clone() и не использовать super.clone(). Важно то, что вы не используете Object.clone().

    Преимущество использования Object.clone() заключается в том, что возвращаемый объект имеет тот же класс времени выполнения, что и объект, для которого он вызывается. С другой стороны, ваш метод всегда создает новый объект ColoredCircle. Поэтому, когда ваш метод testClone() наследуется в подклассе, он все равно будет создавать ColoredCircle, а не экземпляр этого подкласса. Принимая во внимание, что если ваш метод называется super.clone(), он сможет получить экземпляр любого подкласса, которым является текущий экземпляр.

    17.10.2015
  • очень красивое объяснение. 14.12.2017

  • 3

    Cloneable — это интерфейс маркера. Он не содержит методов.

    Дело в том, что метод clone определен в классе Object. Поскольку все классы реализуют класс Object, это означает, что все классы имеют метод clone. Однако не все объекты на самом деле его поддерживают. Некоторые из них просто выкинут CloneNotSupportedException. Но этот метод клонирования является методом native, поэтому точное поведение этого метода не видно в исходном коде Java. Таким образом, ему не хватает прозрачности.

    Интерфейс Cloneable поможет нам распознать, какие классы действительно можно клонировать, а какие нет. По соглашению классы, которые не реализуют Cloneable, будут выдавать CloneNotSupportedException.

    Примечание. метод clone также помечен protected. Таким образом, также принято переопределять его, чтобы сделать его public в поддерживающих классах.


    Дизайн clone был представлен в JDK1. В наши дни все согласны с тем, что дизайн java clone содержит некоторые недостатки. Некоторые предпочитают просто создавать конструктор клонирования (например, public Color(Color toCopy) {this.color = toCopy.color;})

    14.10.2015
  • это означает, что все классы имеют метод клонирования. Но у большинства классов нет метода public clone. 17.10.2015
  • @newacct действительно, ты хочешь сказать? - Я имею в виду, я упомянул об этом в своем ответе, не так ли? 17.10.2015
  • Помимо самого класса или его подкласса, единственными методами, которые есть у класса, являются общедоступные методы. Таким образом, это утверждение бесполезно, потому что для всех эффектов и целей для обычного кода большинство объектов не имеют доступного метода с именем clone. Кроме того, вы говорите, что не все объекты на самом деле поддерживают его. что опять-таки противопоставляет не все всем, что опять-таки подразумевает, что оно есть у всех. Но не только некоторые объекты не поддерживают его, но и большинство объектов вообще не имеют его с точки зрения кода вне этого класса. 18.10.2015
  • @newacct всегда доступен, даже если это не public. Он доступен для дочерних классов и классов в одном пакете. (не говоря уже об отражении, которое очень актуально в эпоху прокси-объектов и АОП, которые играют все большую роль в java.) 18.10.2015
  • @newacct, во-вторых, не все действительно создано для контраста. В то время как все объекты имеют его, большинство из них выдают CloneNotSupportedException, который всплывает на всем пути от исходного кода уровня. 18.10.2015
  • @newacct в комментариях к вашему последнему утверждению: я не могу не согласиться. Все объекты действительно имеют метод clone. Это просто факт. И я думаю, я могу согласиться с тем, что это метод без тела на уровне Java, но это относится ко всем нативным методам. Тело находится на уровне C++. 18.10.2015
  • Новые материалы

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

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: wedx@cp9.ru