Почему Java не имеет конструктора копирования?

Почему Java не поддерживает конструктор копирования, как на C ++?

Java делает. Они просто не называются неявно, как на C ++, и я подозреваю, что это ваш реальный вопрос.

Во-первых, конструктор копирования – это не что иное, как:

public class Blah { private int foo; public Blah() { } // public no-args constructor public Blah(Blah b) { foo = b.foo; } // copy constructor } 

Теперь C ++ косвенно вызовет конструктор копирования с утверждением, подобным этому:

 Blah b2 = b1; 

Клонирование / копирование в этом случае просто не имеет смысла в Java, потому что все b1 и b2 являются ссылками, а не такими объектами, как на C ++. В C ++ этот оператор создает копию состояния объекта. В Java он просто копирует ссылку . Состояние объекта не копируется, поэтому неявное обращение к конструктору копирования бессмысленно.

И это все на самом деле.

От Брюса Эккеля :

Почему [конструктор копирования] работает на C ++, а не на Java?

Конструктор копирования является фундаментальной частью C ++, так как он автоматически создает локальную копию объекта. Однако приведенный выше пример доказывает, что он не работает для Java. Зачем? В Java все, что мы манипулируем, является дескриптором, в то время как на C ++ вы можете иметь объекты, подобные дескрипторам, и вы также можете передавать объекты напрямую. Вот что такое конструктор экземпляров C ++ для: когда вы хотите взять объект и передать его по значению, тем самым дублируя объект. Поэтому он отлично работает на C ++, но вы должны иметь в виду, что эта схема не работает на Java, поэтому не используйте ее.

(Я рекомендую прочитать всю страницу – на самом деле, начните здесь ).

Я думаю, что ответ на этот вопрос очень интересный.

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

Поскольку вы получаете доступ только к объектам с помощью копируемых ссылок, фактическое количество раз, когда вам нужно скопировать объект, значительно сокращается (например, на C ++ просто передача объекта функции (по значению) приводит к созданию новых объектов, созданных копиями, в Java передается только ссылка на объект). Дизайнеры, вероятно, полагали, что для остальных применений будет достаточно clone ().

Это только мое мнение (я уверен, что есть оправданный ответ)

Конструкторы копирования в C ++ в первую очередь полезны, когда вы отправляете или возвращаете экземпляры classов по значению, так как это происходит, когда конструктор копирования прозрачно активируется.

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

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

Думаю, они решили, что вы можете просто сделать метод clone ()?

Это похоже. Когда мелкие копии в порядке, у вас есть [clone ()] ( http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone ()), и когда они не работают, Вам нужно реализовать глубокую копию, как и C ++.

Единственное существенное отличие состоит в том, что это скорее фабричный метод, чем собственный конструктор, но с точки зрения гибкости и тестируемости это, вероятно, хорошо.

Я не очень программист на C ++, но, похоже, я помню правило о «трех amigos» – конструкторе копирования, операторе присваивания и деструкторе. Если у вас есть, то вам, вероятно, понадобятся все три.

Может быть, без деструктора на языке, они не хотели включать конструктор копирования? Просто догадка.

Ну, может. Он просто не создается неявно. Если бы я должен был догадаться, это, вероятно, связано с тем, что объекты Java всегда выделены в виде кучи.

В C ++ конструктор экземпляра по умолчанию является мелкой по размеру копией. Если class владеет памятью, выделенной в куче (через необработанный указатель), это заставит копию совместно использовать оригиналы с оригиналом, чего вы не хотите.

Представьте себе, что Java имеет такое поведение. Любой class, у которого есть поля, которые являются объектами (читай: по сути, все они), будет иметь неправильное поведение, и вам нужно будет переопределить его самостоятельно. В 99% случаев вы никому не помогли. Кроме того, вы просто создали тонкую ловушку для себя – представьте, что вы случайно забыли переопределить конструктор копии по умолчанию. Если он был создан по умолчанию, и вы пытаетесь его использовать, компилятор вообще не будет жаловаться, но ваша программа будет плохо себя вести во время выполнения.

Даже если они создали конструктор копии по умолчанию, который выполняет глубокую копию, я не уверен, что это было бы особенно полезно. Мало того, что вы, как правило, выполняете меньше копий на Java, чем C ++, но вы не всегда хотите, чтобы скопировать поле.

Объекты, которые вы только что являетесь, и объекты, на которые вы ссылаетесь, потому что они вам нужны, но не отвечают за, одинаковы – просто поля. Собственность и заимствование не являются понятиями первого classа. Для объектов, которые у вас есть, вы хотите их глубоко скопировать (если они не являются неизменными, и в этом случае вам не следует беспокоиться), а для объектов, на которые вы просто держите ссылку, вы хотите скопировать ссылку.

Я бы сказал, что конструктор копирования, который просто бездумно глубоко копирует все, не подходит для многих classов. Конечно, более чем мелкое копирование по умолчанию.

Java имеет экземпляр Constructor
Примечание: вместо демо d2 = новая демонстрация (d1) , вы можете написать демо d2 = d1
Основное различие b / w два
demo d2 = новая демонстрация (d1) означает, что создается новый объект и выделена память. Но
demo d2 = d1 подразумевает создание только ссылочной переменной, которая использует тот же адрес памяти объекта d1 и, следовательно, d2 не выделяет отдельную память.

Синтаксис конструктора копирования:
См. Ниже Пример первого Копировать конструктор очень просто :))
classname (int datafield) // Простой конструктор
{
this.datafield = DataField;
}

classname (объект classа)
{
datafield = object.datafield; // См. ниже пример
}
Теперь для звонков
{

classname obj = new classname ();

classname anotherObject = obj; // или classname anotherObject = new classname (obj)

}

  classная демонстрация
 {
     частная длина int;

     частная внутренняя ширина;

     частный внутренний радиус;

     demo (int x, int y)

     {
         длина = х;
         Широта = у;
     }
     int area ()
     {
         длина возврата * ширина;
     }

     // Копировать конструктор
     demo (demo obj)
     {
         длина = obj.length;
         Широта = obj.breadth;
     }


     public static void main (String args [])
     {
         demo d1 = новое демо (5,6);
         demo d2 = новая демонстрация (d1); // Вызов структуры копирования
         System.out.println («Область для объекта d1 =» + d1.area ());
         System.out.println («Область для объекта d2 =» + d2.area ());

     }
 }

  • Сообщение jsoup и cookie
  • Как правильно декодировать параметры юникода, переданные в сервлет
  • Как найти файлы, соответствующие строке подстановки в Java?
  • Можем ли мы создать экземпляр интерфейса на Java?
  • Как бы вы реализовали кеш LRU в Java?
  • Что такое Java EE?
  • Есть ли рекомендуемый способ использования шаблона Observer в MVP с использованием GWT?
  • Как дождаться завершения всех streamов, используя ExecutorService?
  • Java не может найти основной class
  • Лучший способ автоматической привязки данных между базой данных и пользовательским интерфейсом в приложении java swing?
  • PrintWriter и PrintStream никогда не бросают IOExceptions
  • Давайте будем гением компьютера.