Java: 인스턴스 상세 복제/복사에 권장되는 솔루션
자바에서 인스턴스의 딥 클론/복사를 하는 권장 방법이 있는지 궁금합니다.
3가지 해결책이 있는데 몇 가지를 놓쳤을 수 있으니 당신의 의견을 듣고 싶습니다.
편집: Bohzo 프로포지톤을 포함시키고 질문을 구체화합니다.이것은 얕은 클로닝보다는 깊은 클로닝에 관한 것입니다.
직접 실행:
속성 뒤에 수동 속성으로 복제를 코드화하고 가변 인스턴스도 복제되는지 확인합니다.
라이선스:
- 수행 내용 제어
실행 - 퀵 실행
삭제:
와
발생, 가능 속성) - "(복사/실패), "실패", "실패", "실패"
반사 사용:
독자적인 리플렉션툴이나 외부 도우미(jakarta common-beans 등)를 사용하면, 1행으로 작업을 실시하는 범용 카피 방법을 간단하게 작성할 수 있습니다.
라이선스:
- 쓰기 쉽다
없음 - 유지 보수 없음 - 유지 보수 없음
삭제:
에 대한 가 덜하다. - 무슨 일이 일어나는지 덜하다.
- - 이 서브오브젝트도 복제하지 않는 경우.
가 느리다 - 실행 속도가 느리다
클론 프레임워크 사용:
하세요. : 음음음 다다 、 다다다다다 다다다。
Serialization
딥 Java
★★
라이선스:
-반사-반사-반사-반사-반사-반사와똑같다
이 복제될지에 더 을 가지고 있습니다. - 복제될지에 대한 통제력을 강화합니다.
삭제:
한 인스턴스는 됩니다. - 층 、 계 、 - 、 - 、 - 、 - - - - - - - - - 。
수 . - 실행이 느릴 수 있습니다.
런타임에 클론을 쓰기 위해 바이트 코드 계측을 사용합니다.
javassit, BCEL 또는 cglib을 사용하여 한 손으로 쓴 것과 같은 속도로 전용 클론을 생성할 수 있습니다.이 목적을 위해 이 도구들 중 하나를 사용하는 lib를 아는 사람이 있습니까?
가가 여기 것? ??
떤떤것 ?을 ?? ???? ???
고마워요.
전체 개체 계층 복제의 경우:
commons-lang Serialization Utils - 시리얼라이제이션 사용 - 모든 클래스가 제어 하에 있으며 강제로 구현할 수 있는 경우
Serializable
.Java Deep Cloning Library - 리플렉션 사용 - 클론하고 싶은 클래스 또는 오브젝트가 제어 불능(서드파티 라이브러리)으로 구현이 불가능한 경우
Serializable
「」를 실장하고 않은Serializable
.
얕은 복제(첫 번째 수준 속성만 복제):
대부분의 경우 Commons-BeanUtils.
Spring Bean Utils - 이미 spring을 사용하고 있기 때문에 클래스 패스에 이 유틸리티가 있는 경우.
Do-it-Yourself 옵션을 일부러 생략했습니다.위의 API는 무엇을 복제할 것인지 무엇을 복제하지 않을 것인지를 적절하게 제어합니다(예를 들어, 사용).transient
, 또는String[] ignoreProperties
따라서 바퀴를 재창조하는 것은 바람직하지 않습니다.
Joshua Bloch의 책에는 "Item 10: Override Clone Judiciously"라는 제목의 장 전체가 있는데, 이 장에서는 대부분의 경우 클론을 덮어쓰는 것이 왜 나쁜 생각인지에 대해 설명합니다. 왜냐하면 클론의 자바 사양은 많은 문제를 일으키기 때문입니다.
그는 몇 가지 대안을 제시합니다.
컨스트럭터 대신 공장 패턴을 사용합니다.
public static Yum newInstance(Yum yum);
복사 생성자 사용:
public Yum(Yum yum);
Java의 모든 컬렉션 클래스는 복사 컨스트럭터를 지원합니다(예를 들어 새로운 ArrayList(l);).
버전 2.07 Kryo는 얕은/깊은 복제를 지원합니다.
Kryo kryo = new Kryo();
SomeClass someObject = ...
SomeClass copy1 = kryo.copy(someObject);
SomeClass copy2 = kryo.copyShallow(someObject);
Kryo는 속도가 빠릅니다.및 그들의 페이지에서 Kryo를 생산에 사용하는 회사의 목록을 찾을 수 있습니다.
메모리에서 XStream to XML/fromXML 을 사용합니다.매우 빠르고, 오랫동안 존재해 왔으며, 강해지고 있습니다.개체는 직렬화할 필요가 없으며 XStream은 사용할 수 있지만 리플렉션도 필요하지 않습니다.XStream은 동일한 개체를 가리키는 변수를 식별할 수 있으며 실수로 인스턴스의 전체 복사본을 두 개 만들지 않습니다.그와 같은 많은 세부사항들이 수년간에 걸쳐서 결정되었다.나는 그것을 몇 년 동안 사용해 왔고 그것은 아주 좋다.그것은 당신이 상상하는 것만큼 사용하기 쉽습니다.
new XStream().toXML(myObj)
또는
new XStream().fromXML(myXML)
복제하려면
new XStream().fromXML(new XStream().toXML(myObj))
보다 간결하게:
XStream x = new XStream();
Object myClone = x.fromXML(x.toXML(myObj));
복잡한 오브젝트나 퍼포먼스가 중요하지 않은 경우에는 gson을 사용하여 오브젝트를 json 텍스트로 시리얼화한 후 텍스트를 역직렬화하여 새로운 오브젝트를 가져옵니다.
반사에 기초한 gson은 대부분의 경우 작동하지만 다음 사항은 제외한다.transient
필드가 복사되지 않고 원인과 함께 순환 참조가 있는 객체가 복사되지 않습니다.StackOverflowError
.
public static <ObjectType> ObjectType Copy(ObjectType AnObject, Class<ObjectType> ClassInfo)
{
Gson gson = new GsonBuilder().create();
String text = gson.toJson(AnObject);
ObjectType newObject = gson.fromJson(text, ClassInfo);
return newObject;
}
public static void main(String[] args)
{
MyObject anObject ...
MyObject copyObject = Copy(o, MyObject.class);
}
경우에 따라 다르지요.
속도를 위해 DIY를 사용합니다.방탄에는 반사를 사용합니다.
참고로 일부 개체는 오버라이드된 직렬화 메서드(readObject/writeObject)를 제공할 수 있으며 오류가 발생할 수 있으므로 직렬화는 refl과 동일하지 않습니다.
좋은 해시 코드()와 등가() 메서드를 조합하여 유닛 테스트에서 쉽게 증명할 수 있는 DIY 방법을 추천합니다.
Object.clone()을 재정의하고 먼저 super.clone()을 호출한 다음 전체 참조에서 ref = ref.clone()을 호출하는 것이 좋습니다.어느 정도 Do it yourself 접근 방식이지만 코딩이 다소 덜 필요합니다.
딥 클로닝 구현 이렇게 클로닝하는 모든 클래스에서 시리얼 가능
public static class Obj implements Serializable {
public int a, b;
public Obj(int a, int b) {
this.a = a;
this.b = b;
}
}
그리고 다음 기능을 사용합니다.
public static Object deepClone(Object object) {
try {
ByteArrayOutputStream baOs = new ByteArrayOutputStream();
ObjectOutputStream oOs = new ObjectOutputStream(baOs);
oOs.writeObject(object);
ByteArrayInputStream baIs = new ByteArrayInputStream(baOs.toByteArray());
ObjectInputStream oIs = new ObjectInputStream(baIs);
return oIs.readObject();
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
이렇게요.Obj newObject = (Obj)deepClone(oldObject);
언급URL : https://stackoverflow.com/questions/2156120/java-recommended-solution-for-deep-cloning-copying-an-instance
'programing' 카테고리의 다른 글
이 두 어레이를 연결할 수 없는 이유는 무엇입니까? (0) | 2022.06.25 |
---|---|
가져올 때 기호를 확인할 수 없습니다. (0) | 2022.06.25 |
C의 함수 포인터는 어떻게 작동합니까? (0) | 2022.06.25 |
Trix HTMLSanitizer를 재정의하여 클래스에서 스판 태그를 허용하는 방법 (0) | 2022.06.25 |
v-for를 사용하여 반복할 때 vuej가 크래시됨 (0) | 2022.06.25 |