Program Tip

Java에 복사 생성자가없는 이유는 무엇입니까?

programtip 2020. 11. 13. 23:58
반응형

Java에 복사 생성자가없는 이유는 무엇입니까?


Java가 C ++에서와 같은 복사 생성자를 지원하지 않는 이유는 무엇입니까?


자바는 그렇습니다. 그들은 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;

모든 b1 및 b2가 참조이고 C ++에서와 같은 값 객체가 아니기 때문에 해당 인스턴스에서 복제 / 복사하는 것은 Java에서 의미가 없습니다. C ++에서이 문은 객체의 상태를 복사합니다. Java에서는 단순히 참조 를 복사합니다 . 객체의 상태는 복사되지 않으므로 암시 적으로 복사 생성자를 호출하는 것은 의미가 없습니다.

그리고 그게 전부입니다.


에서 브루스 에켈 (Bruce Eckel) :

[복사 생성자]가 Java가 아닌 C ++에서 작동하는 이유는 무엇입니까?

복사 생성자는 자동으로 객체의 로컬 복사본을 만들기 때문에 C ++의 기본 부분입니다. 그러나 위의 예는 Java에서 작동하지 않음을 증명합니다. 왜? Java에서는 우리가 조작하는 모든 것이 핸들이지만 C ++에서는 핸들과 같은 엔티티를 가질 수 있으며 객체를 직접 전달할 수도 있습니다. 이것이 C ++ 복사 생성자의 용도입니다. 객체를 가져와 값으로 전달하여 객체를 복제하려는 경우입니다. 따라서 C ++에서는 잘 작동하지만이 스키마는 Java에서는 실패하므로 사용하지 마십시오.

(전체 페이지를 읽는 것이 좋습니다 . 실제로 여기 에서 시작 하세요 .)


이에 대한 답이 매우 흥미 롭다고 생각합니다.

우선 Java에서는 모든 객체가 힙에 있고 포인터가 없지만 "참조"가 있다고 생각합니다. 참조에는 복사 시맨틱이 있으며 Java는 내부적으로 참조 횟수를 추적하므로 가비지 수집기가 제거해도 안전한지 알 수 있습니다.

복사 가능한 참조를 통해서만 객체에 액세스하기 때문에 객체를 복사해야하는 실제 횟수가 크게 줄어 듭니다 (예를 들어 C ++에서는 객체를 함수에 전달하기 만하면 (값으로) Java에서 새 객체가 복사 생성됩니다.) 객체에 대한 참조 만 전달됩니다). 디자이너는 아마도 clone ()이 나머지 용도로 충분하다고 생각했을 것입니다.

 


이것은 내 의견 일뿐입니다 (정당한 대답이 있다고 확신합니다)

C ++의 복사 생성자는 복사 생성자가 투명하게 활성화되는 경우이기 때문에 값으로 클래스의 인스턴스를 보내거나 반환 할 때 주로 유용합니다.

Java에서는 모든 것이 참조로 반환되고 VM이 동적 할당에 맞춰져 있기 때문에 복사 생성자의 복잡성에 대한 정당성이 실제로 없었습니다.

또한 모든 것이 참조 용이므로 개발자는 종종 필드를 복제하는 방법에 대한 자체 구현 및 결정을 제공해야합니다.


대신 clone () 메서드를 만들 수 있다고 생각 했나요?


그렇습니다. 얕은 복사본이 정상이면 [clone ()] ( http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone ())이 있고 그렇지 않은 경우 t 당신은 C ++처럼 깊은 카피를 구현해야합니다.

유일한 실질적인 차이점은 생성자 자체가 아니라 팩토리 방법이라는 것입니다.하지만 유연성과 테스트 가능성 측면에서 그것은 아마도 좋은 것입니다.


저는 C ++ 프로그래머는 아니지만 복사 생성자, 할당 연산자, 소멸자 등 "세 가지 아미고"에 대한 규칙을 기억하는 것 같습니다. 하나가 있으면 세 가지가 모두 필요할 것입니다.

그렇다면 언어에 소멸자가 없으면 복사 생성자를 포함하고 싶지 않았을까요? 그냥 추측입니다.


글쎄요. 암시 적으로 생성되지는 않습니다. 추측해야한다면 Java 객체가 항상 힙 할당된다는 사실과 관련이있을 것입니다.

C ++에서 기본 복사 생성자는 멤버 단위의 단순 복사입니다. 클래스가 힙에 할당 된 메모리 (원시 포인터를 통해)를 소유하면 복사본이 원본과 내부를 공유하게되는데, 이는 원하는 것이 아닙니다.

Java가 이러한 동작을 가지고 있다고 잠시 상상해보십시오. 객체 인 필드가있는 모든 클래스 (기본적으로 모두 읽기)는 잘못된 동작을 가지므로 직접 재정의해야합니다. 99 %의 경우에는 아무 문제도 해결하지 못했습니다. 또한, 당신은 자신을위한 미묘한 함정을 만들었습니다. 실수로 기본 복사 생성자를 재정의하는 것을 잊었다 고 상상해보십시오. 기본적으로 생성되어 사용하려고하면 컴파일러는 전혀 불평하지 않지만 프로그램은 런타임에 오작동합니다.

딥 복사를 수행하는 기본 복사 생성자를 만들었더라도 이것이 특히 유용 할 것 같지는 않습니다. 어쨌든 C ++보다 Java에서 더 적은 복사를 수행하는 경향이있을뿐만 아니라 항상 필드를 딥 복사하고 싶지는 않습니다.

방금 소유 한 개체와 필요하기 때문에 참조를 보유하는 개체는 동일하지만 책임이없는 개체는 필드뿐입니다. 소유권과 차용은 일류 개념이 아닙니다. 소유 한 객체의 경우 딥 복사를 원하고 (불변이 아닌 경우에는 신경 쓰지 말아야 함) 참조 만 유지하는 객체의 경우 참조를 복사하려고합니다.

나는 모든 것을 무심코 깊게 복사하는 복사 생성자는 많은 클래스에도 적합하지 않을 것이라고 주장합니다. 하지만 기본적으로 얕은 복사 이상입니다.


자바는 생성자 복사
주 : 대신에 데모 D2 = 새로운 데모 (D1) , 당신이 쓸 수 d1에서 데모 D2 =을
주요 차이 B /이 승
데모 D2 = 새로운 데모 (D1)이 새로운 객체가 생성되고이 메모리 그러나 할당을 의미
데모 d2 = d1 은 객체 d1 의 동일한 메모리 주소를 사용하는 참조 변수 만 생성 되므로 d2는 별도의 메모리가 할당되지 않음을 의미합니다.

Syntax of copy constructor:
See below Example first Copy constructor is very easy :))
classname(int datafield) //Simple Constructor
{
this.datafield=datafield;
}

classname(classname object)
{
datafield=object.datafield;//See below example
}
Now for Calling
{

classname obj=new classname();

classname anotherObject=obj;//or 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());

    }
}

참고URL : https://stackoverflow.com/questions/827785/why-doesnt-java-have-a-copy-constructor

반응형