Почему 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());

    }
}