Почему Java не поддерживает конструктор копирования, как в С++?
Почему Java не имеет конструктора копирования?
Ответ 1
Java делает. Они просто не называются неявно, как на С++, и я подозреваю, что ваш реальный вопрос.
Во-первых, конструктор копирования не более чем:
public class Blah {
private int foo;
public Blah() { } // public no-args constructor
public Blah(Blah b) { foo = b.foo; } // copy constructor
}
Теперь С++ косвенно вызовет конструктор копирования с выражением, подобным этому:
Blah b2 = b1;
Клонирование/копирование в этом случае просто не имеет смысла в Java, потому что все b1 и b2 являются ссылками, а не такими объектами, как на С++. В С++ этот оператор создает копию состояния объекта. В Java он просто копирует ссылку. Состояние объекта не копируется, поэтому неявно вызов конструктора копирования не имеет смысла.
И это все на самом деле.
Ответ 2
От Брюс Экель:
Почему [конструктор копирования] работает на С++, а не на Java?
Конструктор копирования является фундаментальным часть С++, так как она автоматически делает локальную копию объекта. Все же пример выше доказывает, что он не работает для Java. Зачем? В Java все, что мы манипулируем, - это, а на С++ - ручные объекты, и вы также можете обходите объекты напрямую. То, что конструктор копии С++ для: когда вы хотите взять объект и передать его по значению, таким образом дублируя объект. Так оно работает отлично в С++, но вы должны что эта схема не работает в Java, поэтому не используйте его.
(Я рекомендую прочитать всю страницу - на самом деле, вместо здесь)
Ответ 3
Я думаю, что ответ на этот вопрос очень интересный.
Во-первых, я считаю, что в Java все объекты находятся в куче, и пока у вас нет указателей, у вас есть "Ссылки". Ссылки имеют симпозиумы копирования, а java внутренне отслеживает количество ссылок, чтобы сборщик мусора знал, в чем можно избавиться.
Поскольку вы получаете доступ только к объектам с помощью копируемых ссылок, фактическое количество раз, когда вам нужно скопировать объект, значительно уменьшается (например, на С++ просто передача объекта функции (по значению) приводит к созданию новых объектов, в Java передается только ссылка на объект). Дизайнеры предположили, что для остальных применений будет достаточно clone().
Ответ 4
Это только мое мнение (я уверен, что есть оправданный ответ)
Конструкторы копирования в С++ в первую очередь полезны, когда вы отправляете или возвращаете экземпляры классов по значению, так как это происходит, когда конструктор копирования прозрачно активирован.
Так как в Java все возвращается по ссылке, а виртуальная машина ориентирована на динамическое распределение, на самом деле не было оправдания сложностей конструктора копирования.
Кроме того, поскольку все по ссылке, разработчику часто приходится предоставлять свою собственную реализацию и решение о том, как клонировать поля.
Ответ 5
Угадайте, что они решили, что вы можете просто сделать метод clone()?
Ответ 6
Это как-то. Когда мелкие копии в порядке, у вас есть [clone()] (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone()), и когда они не нужны, вам нужно реализовать глубокую копию просто как С++.
Единственное существенное отличие состоит в том, что это метод factory, а не собственный конструктор, но с точки зрения гибкости и проверяемости, что, вероятно, хорошо.
Ответ 7
Я не очень программист на С++, но, похоже, я помню правило о "трех amigos" - конструкторе копирования, операторе присваивания и деструкторе. Если он у вас есть, вам наверняка понадобится все три.
Итак, возможно, без деструктора на языке, они не хотели включать конструктор копирования? Просто предположим.
Ответ 8
Ну, может. Он просто не создается неявно. Если бы мне пришлось угадать, это, вероятно, связано с тем, что объекты Java всегда выделены в виде кучи.
В С++ конструктор экземпляра по умолчанию является мелкосерийной копией. Если класс владеет памятью, выделенной в куче (с помощью необработанного указателя), это заставит копию совместно использовать оригиналы с оригиналом, который не является тем, что вы хотите.
Представьте себе, что Java имеет такое поведение. Любой класс, у которого есть поля, которые являются объектами (читай: по сути, все они), будет иметь неправильное поведение, и вам нужно будет переопределить его самостоятельно. В 99% случаев вы никому не помогли. Кроме того, вы просто создали тонкую ловушку для себя - представьте, что вы случайно забыли переопределить конструктор копии по умолчанию. Если он был создан по умолчанию, и вы пытаетесь его использовать, компилятор вообще не будет жаловаться, но ваша программа будет плохо себя вести во время выполнения.
Даже если они создали конструктор копии по умолчанию, который выполняет глубокую копию, я не уверен, что это было бы особенно полезно. Мало того, что вы, как правило, выполняете меньше копий на Java, чем С++, но вы не всегда хотите, чтобы скопировать поле.
Объекты, которые вы только что являетесь владельцем, и объекты, на которые вы ссылаетесь, потому что они вам нужны, но не отвечают за, одинаковы - просто поля. Собственность и заимствование не являются понятиями первого класса. Для объектов, которые у вас есть, вы хотите их скопировать (если они не являются неизменными, и в этом случае вам не следует беспокоиться), а для объектов, на которые вы просто держите ссылку, вы хотите скопировать ссылку.
Я бы сказал, что конструктор копирования, который просто бездумно глубоко копирует все, не подходит для многих классов. Конечно, более чем мелкое копирование по умолчанию.
Ответ 9
Java имеет копировать конструктор
Примечание: вместо демо d2 = новая демонстрация (d1) вы можете написать демо d2 = d1
Основное различие b/w two
demo d2 = новое демо (d1) означает, что создается новый объект, и это
выделенная память. Но
demo d2 = d1 подразумевается создание только ссылочной переменной
который использует тот же адрес памяти объекта d1 и, следовательно, d2 не назначен
разделенной памяти.
Синтаксис конструктора копирования:
См. Ниже Пример сначала Копировать конструктор очень просто:))
classname (int datafield)//Простой конструктор
{
this.datafield = DataField;
}
classname (объект класса)
{
datafield = object.datafield;//См. ниже пример
}
Теперь для звонков
<Б > {
classname obj = new classname();
classname anotherObject = obj;//или classname anotherObject = new classname (obj)
}
class demo { private int length; private int breadth; private int radius; demo(int x,int y) { length=x; breadth=y; } int area() { return length*breadth; } //Copy Constructor demo(demo obj) { length=obj.length; breadth=obj.breadth; } public static void main(String args[]) { demo d1=new demo(5,6); demo d2=new demo(d1);//Invokes Copy Constructure System.out.println("Area for d1 object="+d1.area()); System.out.println("Area for d2 object="+d2.area()); } }