복제 메소드와 java의 복사 생성자. 어느 것이 올바른 해결책인가. 어디에서 각 경우를 사용합니까?Clone() vs 복사 생성자 - Java에서 권장되는
답변
복제가 손상되었으므로 사용하지 마십시오. 그것은 그 개체의 동일한 복사본을 생성하지 :
이 방법을 선호 역효과 에서 주문을 방지하기 위해 적절한 주문을 필요로 더 http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspxObject 클래스 의 clone 메소드는 할 이제까지 수없는 순수 자바 방법은 무엇 을하는 다소 마법의 방법이다. Java 컴파일러 *의 베타 - 릴리스 날짜 이후 원시 객체 슈퍼 클래스에있었습니다. 그리고, 모든 고대 마법처럼, 사본 오브젝트
Foo copyFoo (Foo foo){ Foo f = new Foo(); //for all properties in FOo f.set(foo.get()); return f; }
읽기 예기치 않게
음, 복제가 손상되지 않았습니다. 왜 그렇게 생각하니? 그것을 덮어 씌우지 않으면 작동하지 않기 때문입니다 - 음, 그 계약입니다. – Bozho
@Bozho, Effective Java 2 판 _을 읽어보십시오. Bloch는 아주 잘 설명했습니다. Doug Lea는 배열 복제 (http://www.artima.com/intv/bloch13.html)를 제외하고는 더 이상'clone()'을 사용하지 않습니다. – polygenelubricants
왜 복제가 더 간단하지 않을 수 있는지 이해가되지 않습니다. 이것이 선택인가? 아니면 일반적인 경우에 그 뒤에 정말 가혹한 문제가 있습니까? – LB40
clone()
은 기본적으로 작동하지 않는다는 것을 명심하십시오. Cloneable
을 구현하고 clone()
메서드를 public
에서 재정의해야합니다.
바람직하다 몇 가지 대안이있다합니다 (clone()
방법은 다른 답변에 명시된 바와 같이 설계 문제를 많이 가지고 있기 때문에)와 복사 생성자는 수동 작업이 필요합니다 :
BeanUtils.cloneBean(original)
(가) 작성Object.clone()
에 의해 생성 된 것과 같은 얕은 클론. (이 클래스는 commons-beanutils입니다.)SerializationUtils.clone(original)
은 딥 클론을 생성합니다. (전체 특성 그래프가 복제되는 즉,뿐만 아니라 첫 번째 수준) (commons-lang에서)하지만, 모든 클래스는Serializable
Java Deep Cloning Library도
Serializable
페이지를 구현할 필요없이 깊은 복제를 제공합니다 구현해야합니다 : How to properly override clone method?. 클로닝은 Java에서 깨졌습니다. 이므로 매우 어렵습니다.을 사용하면 올바르게 처리 할 수 있습니다. 심지어 은 실제로 많이 제공하지 않습니다.이므로 번거 로움이 없습니다.
'java.lang.Object'에서 상속받은'final' 클래스가있을 때 훨씬 쉽게 얻을 수 있습니다. 클래스가 변경 가능한 데이터 구조를 포함하므로 (따라서 딥 카피가 필요함) 까다로운 일이지만, 동일한 도전이 복사 생성자에도 나타날 수 있습니다. – IceArdor
복사 생성자는 클래스 형식을 복사 생성자의 형식으로 제한합니다. 예를 생각해
// Need to clone person, which is type Person
Person clone = new Person(person);
이것은 person
이 Person
의 서브 클래스를 할 수 있다면 작업 (또는 Person
가 인터페이스 인 경우)하지 않습니다. 이것은 복제본의 전체 요점입니다. 즉, 런타임에 적절한 유형을 동적으로 복제 할 수 있다는 것입니다 (복제가 제대로 구현되었다고 가정).
Person clone = (Person)person.clone();
또는
Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer
지금
person
는
clone
가 제대로 구현되는 것을 가정
Person
의 모든 유형이 될 수 있습니다.
'clone '의 적절한 행동은 그 메소드 자체가'super.clone()'을 호출하는 것이기 때문에 누군가가 한 번 복제의 적절한 구현이'super.clone()'보다는'new'를 포함해야한다고 제안한 것은 유감스러운 일입니다. 'super.clone()'을 호출한다 (또는 객체를위한 내장 된 멤버 별 복제이다). 'super.clone()'이'new' 호출을 끝내면'clone()'의 완전히 완전히 깨진 동작은'new' 자체를 호출하는 것뿐입니다. 그러나 모든 자식 클래스는'clone()'을 자식 클래스가'clone()'을 오버라이드 (override) 할 필요가 있을지 어떨지를 마찬가지로 행한다. – supercat
"deep vs shallow"질문은 대부분의 경우 나에게 모호하지 않은 것처럼 보입니다. 'SomeCollection
clone()은 여러 실수 (this question 참조)로 설계되었으므로 피하는 것이 가장 좋습니다. Effective Java 2nd Edition에서
, 항목 11 : 재정의 클론 신중
Cloneable을과 관련된 모든 문제, 그것은 다른 인터페이스를 확장하지 않도록 말을 안전하고 감안할 때 상속을 위해 설계된 클래스 (항목이 17)는 그것을 구현해서는 안됩니다. 의 많은 단점으로 인해 일부 전문가 프로그래머는 을 복제 방법을 재정의하지 않고 단순히 복사 배열 을 제외하고는 절대로 호출하지 않기로 선택합니다. 상속을위한 클래스를 디자인하는 경우 잘 작동하는 보호 된 복제 메서드를 제공하지 않기로 선택하면 은 하위 클래스에서 Cloneable을 구현할 수 없습니다.
이 설명서에서는 복사 생성자가 Cloneable/clone보다 갖는 많은 장점에 대해서도 설명합니다. 그들은 위험 발생하기 쉬운 extralinguistic 객체 생성 메커니즘에 의존하지 않는
- 그들은 마지막 필드 을의 적절한 사용과 충돌하지 않는
- 얇게 문서화 된 규칙을 집행 준수를 요구하지 않습니다
- 불필요한 확인 예외를 throw하지 않습니다.
- 캐스팅이 필요하지 않습니다.
모든 표준 컬렉션에는 복사 생성자가 있습니다. 그것을 써.
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
'원본'을 다른 유형의 목록 (예 :'LinkedList ')으로 사용했을 때'ArrayList'로 복사하고 있습니다. 이것은 복제가 복사 생성자보다 나은 이유입니다. –
큰 슬픔 : Cloneable를/복제 나 생성자도 훌륭한 솔루션입니다 : 내가 구현 클래스를 알고 싶지 않아! (예 : - 동일한 숨겨진 MumbleMap 구현을 사용하여 복사 할지도가있는지도가 있습니다.) 지원되는 경우 사본을 만들고 싶습니다. 그러나 Cloneable에는 clone 메서드가 없으므로 clone()을 호출 할 때 안전하게 형변환 할 수있는 것이 없습니다.
오라클은 최상의 "Copy Object"라이브러리가 무엇이든 관계없이 Oracle을 다음 Java 릴리스의 표준 구성 요소로 설정해야합니다 (아직 숨겨져 있지 않은 경우).
물론 더 많은 라이브러리 (예 : 컬렉션)가 변경 불가능한 경우이 '복사'작업은 사라집니다. 그런 다음 우리는 "빈"패턴보다는 "클래스 불변성"과 같은 것들을 사용하여 Java 프로그램을 설계하기 시작할 것입니다 (깨진 객체를 만들고 좋은 것으로 바뀔 때까지 변형).
프로젝트에서 만드는 값 객체에 대해서는 최소한 다음과 같은 몇 가지 희망이 있습니다. https://projectlombok.org/features/experimental/Wither.html – Roboprog
복사가 쉽다면 이미 가질 것입니다. Java의 일부입니다. 그러나 그렇지 않습니다. 너는 얕은 사본, 깊은 사본, 또는 그 중간 어딘가에 원하는가? 복사하는 대상과 캐스팅 대상에 따라 수업마다 다른 행동을 취하고 있습니까? Generics는 어떻게됩니까? 복사중인 내용이 일반용 매개 변수 일 때 어떤 일이 발생합니까? 이것은 상속없이 변경이 불가능한 이유로 조금 더 쉽게 생각할 수 있지만 Java (언어)의 핵심으로 구워집니다. 어쩌면 가변성을 보장하는 Scala와 같은 언어는 복제 가능성을 더 쉽게 만듭니다. – IceArdor
- 1. VS 2008 자극 복사 생성자 링크 의존성
- 2. 복사 생성자 ++
- 3. 복사 생성자
- 4. 복사 생성자?
- 5. 복사 생성자
- 6. 복사 생성자 초기화 목록
- 7. 복사 생성자 버그
- 8. C++의 복사 생성자
- 9. Matlab 복사 생성자
- 10. 기본 인자가있는 복사 생성자
- 11. C++의 복사 생성자
- 12. 복사 생성자 오류
- 13. 임시 및 복사 생성자
- 14. 는 segfault 복사 생성자
- 15. 복사 생성자 의심
- 16. 복사 생성자와 기본 생성자
- 17. 복사 생성자 선택 해제
- 18. weak_ptr를의 이상한 복사 생성자
- 19. 는 복사 생성자
- 20. 템플릿 생성자 대 템플릿 복사 생성자
- 21. C# 사용자 지정 복사 생성자, 복사 이벤트
- 22. 유니버설 세트 클래스 - 복사 생성자
- 23. 복사 생성자 및 동적 할당
- 24. C++ 복사 생성자 이상한 행동
- 25. 모호한 복사 생성자 vc 2008
- 26. 개인 속성을 사용하여 복사 생성자
- 27. Java에서 파일 복사
- 28. Java에서 기본 생성자 및 상속
- 29. EasyMock : Java에서 생성자 호출 모크
- 30. 생성자, 비 const 복사 생성자, 목록의 생성자를 VS2010으로 이동하십시오.
http://stackoverflow.com/questions/1106102/clone-vs-copy-constructor-vs-factory-method –
'복제본 * *'을 사용하지 마십시오. 아무리해도 * 자신의 사본 솔루션을 찾으십시오. – dimitarvp
복사 생성자가 Object보다 낫습니다.왜냐하면 그들은 우리가 어떤 인터페이스를 구현하도록 강요하지 않거나 예외를 던지지 만, 우리가 반드시해야한다면 그것을 수행 할 수 있습니다. 캐스트가 필요하지 않습니다. 알려지지 않은 객체에 의존하지 않아도됩니다. 부모 클래스가 어떤 계약을 따르거나 아무것도 구현하지 않아도됩니다. 최종 필드 수정 허용, 객체 생성을 완전히 제어 할 수있게하고 초기화 논리를 작성할 수 있습니다. 더 읽기 https://programmingmitra.blogspot.in/2017/01/Java-cloning-copy-constructor-versus-Object-clone-or-cloning.html –