자바 딥 복사(구현 상의 비교 분석)
나 만 의 이유 인지,아니면 정말 이런 순 반사 로 이 루어 진 깊 은 복사 방식 이 존재 하지 않 는 지...(c\#순 반사 로 이 루어 진 것)
하지만 헛수고 라 고 할 수 는 없 잖 아 요.다른 딥 복사 방식 도 찾 았 습 니 다.(하지만 모든 방식 이 합 리 적 이지 않다 고 생각 합 니 다.c\#방식 이 들 어 왔 기 때 문 일 수도 있 습 니 다.마지막 으로 c\#버 전 순 반사 로 딥 복사 코드 를 붙 였 습 니 다)
방식 1:Cloneable 인터페이스 구현,clone 재 작성 방법
실체 류:하나의 타이어 류,하나의 차량 류,차량 에 타이어 가 포함 되 어 있 습 니 다.
/** **/
public class Tire implements Cloneable {
public String color;
public int radius;
public Tire(){}
public Tire(String color, int radius) {
this.color = color;
this.radius = radius;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
/** **/
public class Car implements Cloneable{
public String name;
public String color;
public Tire tire;
public Car() {}
public Car(String name, String color, Tire tire) {
this.name = name;
this.color = color;
this.tire = tire;
}
public void whistle(){
System.out.println(" "+this.name+" ...");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Tire getTire() {
return tire;
}
public void setTire(Tire tire) {
this.tire = tire;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@Test
public void test() throws CloneNotSupportedException {
Tire tire = new Tire("black",100);
Car car = new Car(" ","white",tire);
Car car_copy = (Car)car.clone();
System.out.println("car:"+car.hashCode()+" car.tire:"+car.tire.hashCode());
System.out.println("car_copy:"+car_copy.hashCode()+" car_copy.tire:"+car_copy.tire.hashCode());
car_copy.color = "blue";
System.out.println("car_copy:"+car_copy.color+" car:"+car.color);
}
출력 결과:
car:1223737555 car.tire:906199566
car_copy:542081238 car_copy.tire:906199566
car_copy:blue car:white
결과 적 으로 가능 합 니 다.car 와 carcopy 의 메모리 주 소 는 일치 하지 않 지만,car.tire 와 carcopy.tire 의 메모리 주 소 는 일치 합 니 다."벤츠"차 가 확실히 또 한 대 를 만 들 었 다 는 것 을 설명 하지만 같은 타이어(이런 상황...하하 하)를 사용 합 니 다.좋 습 니 다.즉,tire 의 인용 만 복사 한 것 입 니 다.이것 은 깊이 복사 한 불철저(hashCode()의 값 을 메모리 주소 로 이해 할 수 있 습 니 다)이 라 고 할 수 있 습 니 다.그러면 어떻게 해 야 철저 하고 진정한 깊이 복사 할 수 있 습 니까?Car 클래스 의 clone 방법 수정:
@Override
protected Object clone() throws CloneNotSupportedException {
Car car = (Car)super.clone();
car.tire = (Tire)car.tire.clone();
return car;
}
출력 결과:
car:1223737555 car.tire:906199566
car_copy:542081238 car_copy.tire:1133736492
car_copy:blue car:white
이렇게 해서 최종 적 으로 실현 되 었 습 니 다.그러나 이런 방식 은 프로젝트 에 적합 하지 않 습 니 다.깊이 복사 해 야 하 는 모든 종 류 는 Cloneable 인 터 페 이 스 를 실현 하고 clone 방법 을 덮어 야 합 니 다.다른 종 류 를 인용 할 때 clone 방법 을 수정 해 야 합 니 다.다른 종 류 를 인용 하면 다른 종 류 를 참조 해 야 합 니까?이 건 아니 지..방식 2:직렬 화 와 반 직렬 화 를 통 해 실현(Serializable 인터페이스 실현)
실체 클래스:첫 번 째 방식 과 유사 합 니 다.Serializable 인 터 페 이 스 를 실현 하고 clone 방법 을 제거 합 니 다.
/** **/
@SuppressWarnings("serial")
public class Tire implements java.io.Serializable {
public String color;
public int radius;
public Tire(){}
public Tire(String color, int radius) {
this.color = color;
this.radius = radius;
}
}
/** **/
@SuppressWarnings("serial")
public class Car implements java.io.Serializable{
public String name;
public String color;
public Tire tire;
public Car() {}
public Car(String name, String color, Tire tire) {
this.name = name;
this.color = color;
this.tire = tire;
}
public void whistle(){
System.out.println(" "+this.name+" ...");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Tire getTire() {
return tire;
}
public void setTire(Tire tire) {
this.tire = tire;
}
}
딥 카피 방법:
@SuppressWarnings("unchecked")
public static Object deepClone(Object obj)
{
Object copyObj = null;
ObjectOutputStream out = null;
ObjectInputStream in = null;
try {
//
ByteArrayOutputStream bufferOut = new ByteArrayOutputStream();
out = new ObjectOutputStream(bufferOut);
out.writeObject(obj);
//
ByteArrayInputStream bufferIn = new ByteArrayInputStream(bufferOut.toByteArray());
in = new ObjectInputStream(bufferIn);
copyObj = in.readObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
try{
if(in != null){
in.close();
}
if(out!=null){
out.close();
}
}catch(IOException e){
throw new RuntimeException(e);
}
}
return copyObj;
}
유닛 테스트:
@Test
public void test() throws CloneNotSupportedException {
Tire tire = new Tire("black",100);
Car car = new Car(" ","white",tire);
Car car_copy = (Car)deepClone(car);
System.out.println("car:"+car.hashCode()+" car.tire:"+car.tire.hashCode());
System.out.println("car_copy:"+car_copy.hashCode()+" car_copy.tire:"+car_copy.tire.hashCode());
car_copy.color = "blue";
System.out.println("car_copy:"+car_copy.color+" car:"+car.color);
}
출력 결과:
car:2019524978 car.tire:855703640
car_copy:1407965019 car_copy.tire:545768040
car_copy:blue car:white
결과 집 을 보면 깊 은 복사 가 정확 하 다 는 것 을 알 수 있 지만 각 종 류 는 Serializable 을 실현 해 야 하 는 것 도 적절 하지 않 은 것 같 습 니 다.깊 은 복사 방법 최적화:이 를 범 형 으로 바 꾸 면 복사 할 필요 가 없다(그래,사실 위의 방법 만큼 좋 은 것 도 없다.)
@SuppressWarnings("unchecked")
public static <T> T deepClone(T obj)
{
T copyObj = null;
ObjectOutputStream out = null;
ObjectInputStream in = null;
try {
//
ByteArrayOutputStream bufferOut = new ByteArrayOutputStream();
out = new ObjectOutputStream(bufferOut);
out.writeObject(obj);
//
ByteArrayInputStream bufferIn = new ByteArrayInputStream(bufferOut.toByteArray());
in = new ObjectInputStream(bufferIn);
copyObj = (T)in.readObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
try{
if(in != null){
in.close();
}
if(out!=null){
out.close();
}
}catch(IOException e){
throw new RuntimeException(e);
}
}
return copyObj;
}
직렬 화 와 반 직렬 화 깊 은 복사 와 더 간단 한 실현 방식 이 있 습 니 다.바로 가방 을 안내 해 야 합 니 다(복사 하 는 클래스 도 Serializable 인 터 페 이 스 를 실현 해 야 합 니 다).물론 저 는 클릭->org.apache.comons.lang 을 준비 해 두 었 습 니 다.딥 복사 방법:코드 한 줄 만...
public Object deepClone(Object obj){
return org.apache.commons.lang.SerializationUtils.clone((Serializable)obj);
}
자,자바 의 당분간 은 여기까지 입 니 다.물론 이 두 가지 방식 에 만족 하지 않 습 니 다.-------------------------------------------------
C\#심 복사 반사 실현
다음 방법 은 c\#의 깊 은 복사,순 반사 실현,어떠한 인터페이스 도 실현 할 필요 가 없습니다.
/// <summary>
///
/// </summary>
/// <param name="obj"> </param>
/// <returns> </returns>
private object CopyOjbect(object obj) {
if (obj == null) {
return null;
}
Object targetDeepCopyObj;
Type targetType = obj.GetType();
//
if (targetType.IsValueType == true) {
targetDeepCopyObj = obj;
}
//
else {
targetDeepCopyObj = System.Activator.CreateInstance(targetType); //
System.Reflection.MemberInfo[] memberCollection = obj.GetType().GetMembers();
foreach (System.Reflection.MemberInfo member in memberCollection) {
//
if (member.MemberType == System.Reflection.MemberTypes.Field)
{
System.Reflection.FieldInfo field = (System.Reflection.FieldInfo)member;
Object fieldValue = field.GetValue(obj);
if (fieldValue is ICloneable)
{
field.SetValue(targetDeepCopyObj, (fieldValue as ICloneable).Clone());
}
else
{
field.SetValue(targetDeepCopyObj, CopyOjbect(fieldValue));
}
}//
else if (member.MemberType == System.Reflection.MemberTypes.Property) {
System.Reflection.PropertyInfo myProperty = (System.Reflection.PropertyInfo)member;
MethodInfo info = myProperty.GetSetMethod(false);
if (info != null) {
try {
object propertyValue = myProperty.GetValue(obj, null);
if (propertyValue is ICloneable) {
myProperty.SetValue(targetDeepCopyObj, (propertyValue as ICloneable).Clone(), null);
}
else {
myProperty.SetValue(targetDeepCopyObj, CopyOjbect(propertyValue), null);
}
}
catch (System.Exception ex) {
}
}
}
}
}
return targetDeepCopyObj;
}
이상 의 c\#딥 복사 방식 은 자바 딥 복사(실현 상의 비교 분석)를 완 벽 히 이 기 는 것 이 바로 편집장 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.여러분 께 참고 가 되 고 많은 응원 을 바 랍 니 다.유닛 테스트:
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.