Java 의 객체를 복제본에 어떻게 합니까?

아래 코드는 고려해보십시오.

DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'

DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'

dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'

그래서 '덤' 을 '와' 덤스워 복사합니다를, I want to change '덤' '덤스워 영향을 주지 않고'. 그러나 코드 위에 그렇게 할 수 없습니다. When I '덤', '덤스워 같은 변화의 물결' 의 내용을 변경할 수 있다.

아마 내가 말하는 '덤', Java 복사됩니다 참조로만 때 덤스워 = . 따라서 새로 만들 수 있는 방법이 유지됩니까 '덤' 와 '덤스워 복제본에 할당하십시오'?

해결책

Create a copy 구성자를:

class DummyBean {
  private String dummy;

  public DummyBean(DummyBean another) {
    this.dummy = another.dummy; // you can access  
  }
}

또한 모든 객체에는 클론할 데 사용할 수 있는 방법이 있지만, t # 39 복사합니다를 객체에는 don& 사용한다. # 39 의 it& 너무 쉽게 만들 수 있는 클래스 및 책임질래 부적절한 클론할 메서드입니다. 적어도 그렇게 할 경우 어떤 것인지, 검토완료 조슈아 블로흐 it 에 대한 [유효인 jave] [1] 말할 수 있다.

[1]: http://books.google.com/books? id = = = = = effective+java+clone&amp, 소스, dq, 액화석유가스 (lpg), pg ka2vubqhiwkc&amp pa55&amp pa55&amp bl&;;;; 에이 = = = = zveip5tp5kggwqo1scwgtgyj1ns&amp ots yxghlnv4o4&amp sig en&amp hl, 오이, ct = = = = x&amp cyansqygk8jktgfm-jgcca&amp sa book_result&amp result&amp 레스 섬 ppa54, m1, # 3

해설 (17)
  • Basic:* 객체에는 에서 복사 Java.&lt br/>;

'', 두 개체, 객체 solaris. 알려 obj1 확장자입니다 containedObj1 containedObj2. &lt br/>; ! 입력하십시오. 이미지 여기에 설명을 &lt br/>;

  • 얕은 copying:&lt br/>; 얕은 복사 및 복제본에 동일한 클래스의 인스턴스 '새' 는 모든 칸을 이 새 인스턴스를 반환합니다. * 객체에는 클래스 '는' 클론할 방법 및 대한 지원 기능을 br/&gt 얕은 copying.<; ! 입력하십시오. 이미지 여기에 설명을 &lt br/>;

  • 깊이형 copying:*&lt br/>;

  • 객체가 복사됩니다 함께 깊은 복제본에 때 발생할 수 있는 기능을 객체에는 말한다. 아래 그림과 '후' obj1 깊이형 복제본에 수행되었는지 때문이다. 아니다, 그러나 그 안에 들어 있는 '*' obj1 대뿐입니다 복제되었습니다 객체에는 복제되었습니다 잘 알려져 있다. Java Object 직렬화하지 이용할 수 있다 '는' 를 만드는 데 이 문제가 너무 외곽진입 죄송합니다. 깊이형 복제본입니다. (구체적인 예). &lt br/>; enter 이미지 여기에 설명을!

  • 가능한 Problems:*&lt br/>; '클론' 는 구현하기 위해 까다로운 correctly.&lt br/>; [5], [방어적 복사] # 39 의 더 나은 it& 사용할 수 있는 [복제본에 구성자를] [6] (as @egaga 회신과) 또는 [정적임 팩터리의 방법] [7] .&lt br/>;

  1. 객체가 있는 경우, clone () 는 '방법을 알고 있다' 고 하지만 네가 모르는 객체의 타입은 컴파일 타임에 관심용 문제가 있습니다. Java 는 불렀으매 인터페이스입니다 복제 가능 ''. 실제로 이 인터페이스를 구현할 수 있도록 해야 한다 '' 우리가 원하는 개체의 경우 복제 가능. 도왔으매 한다 '는' 오브ject.c론 금지되었는지 오버라이드합니다 공용 방법을 사용하여 이를 수 있도록 하기 위해 accessible.&lt br/>;
          • 복잡한 객체에는 의 또 다른 문제는 우리가 깊이형 복사 시도하시겠습니까 때 발생합니다. 또한 모든 구성원 객체에는 solaris. 작업자쪽에서 clone () 는 '방법' 이 너무 위험한 com/go/4e6b330a_kr 깊이형 복제본에 한 가정. 모든 코드를 제어됩니다 classes.&lt br/&gt 합니다;;

예를 들어 [오르조지아파체스코먼스트랭.즈리얼리제이션티우스] [8] ([출처] [9]) 방법을 사용하여 깊이형 클론할 직렬화하지 갖게 됩니다. 우리는 그렇게 할 경우 다음 몇 가지 방법으로 유틸리티에는 클론할 콩 오르조지아파체스코먼스트비누티우스 (출처).

  • '콩' 가 클론하려면 클로네빈 따라 사용할 수 있는 속성 및 세터 게터 경우에도 콩 클래스 자체를 복제 가능 구현하십시오 않습니다. '-' 에서 그 대상에 대한 속성 값을 코피프로페르티스 복제할지 콩 볶아 경우를 모두 속성 이름을 같습니다.

[5]: http://www.javapractices.com/topic/TopicAction.do? Id = 15 [6]: http://www.javapractices.com/topic/TopicAction.do? Id = 12 [7]: http://www.javapractices.com/topic/TopicAction.do? Id = 21 [8]: http://commons.apache.org/lang/api-2 # clone% .5/org/apache/commons/lang/serializationutils.html 28java.io.serializable% 29 [9]: http://www.jarvana.com/jarvana/view/commons-lang/commons-lang/2.4/commons-lang-2.4-sources.jar /org/apache/commons/lang/SerializationUtils.java? 포맷 = ok!

해설 (4)

'지금', '가져오기의 패키지 안내물은 오르조지아파체스코먼스트랭.즈리얼리제이션티우스 방법입니다.

SerializationUtils.clone(Object);

예:

this.myObjectCloned = SerializationUtils.clone(this.object);
해설 (4)

아래와 같이 따라갈 뿐이야.

public class Deletable implements Cloneable{

    private String str;
    public Deletable(){
    }
    public void setStr(String str){
        this.str = str;
    }
    public void display(){
        System.out.println("The String is "+str);
    }
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

언제 어디서나 간편하게 수행할 가져올 또 다른 객체에는 클론한. 에드그:

Deletable del = new Deletable();
Deletable delTemp = (Deletable ) del.clone(); // this line will return you an independent
                                 // object, the changes made to this object will
                                 // not be reflected to other object
해설 (7)

반사 API 를 사용하여 해답 없는 이유는?

private static Object cloneObject(Object obj){
        try{
            Object clone = obj.getClass().newInstance();
            for (Field field : obj.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                field.set(clone, field.get(obj));
            }
            return clone;
        }catch(Exception e){
            return null;
        }
    }

39 it&; s really simple.

편집: 자식 객체는 포함시키십시오 통해 반복

private static Object cloneObject(Object obj){
        try{
            Object clone = obj.getClass().newInstance();
            for (Field field : obj.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                if(field.get(obj) == null || Modifier.isFinal(field.getModifiers())){
                    continue;
                }
                if(field.getType().isPrimitive() || field.getType().equals(String.class)
                        || field.getType().getSuperclass().equals(Number.class)
                        || field.getType().equals(Boolean.class)){
                    field.set(clone, field.get(obj));
                }else{
                    Object childObj = field.get(obj);
                    if(childObj == obj){
                        field.set(clone, clone);
                    }else{
                        field.set(clone, cloneObject(field.get(obj)));
                    }
                }
            }
            return clone;
        }catch(Exception e){
            return null;
        }
    }
해설 (10)

내가 Google& # 39 에 JSON 라이브러리를 사용하여 새 인스턴스를 만듭니다 직렬화할 그런 시리얼화된 객체에는. 몇 번의 않니다 깊이형 복제본에 제한 사항은 다음과 같습니다.

  • t, 모든 재귀 참조입니다 좁히어 can& # 39.

  • it won& # 39, t 복제본에 어레이에는 다양한 유형

  • 시스템 및 t # 39, 또는 it won& 클래스를 찾을 인스턴스화합니다 열거합니다 입력해야 합니다

  • 클래스에서 문장열 선언할 교도관님도요 캡슐화됨 할 수 있습니다.

난 또 이 클래스 저장하라는 사용자 설정, windows 및 이것저것 스크램블된 다시 로드했습니다 dell. 런타임용으로 개발하십시오. 아주 쉽게 사용할 수 있으며 효과적이다.

import com.google.gson.*;

public class SerialUtils {

//___________________________________________________________________________________

public static String serializeObject(Object o) {
    Gson gson = new Gson();
    String serializedObject = gson.toJson(o);
    return serializedObject;
}
//___________________________________________________________________________________

public static Object unserializeObject(String s, Object o){
    Gson gson = new Gson();
    Object object = gson.fromJson(s, o.getClass());
    return object;
}
       //___________________________________________________________________________________
public static Object cloneObject(Object o){
    String s = serializeObject(o);
    Object object = unserializeObject(s,o);
    return object;
}
}
해설 (2)

정말 그냥 객체에 대한 참조가 있다. 경우 복제 가능 '' 는 객체에는 클론할 수 있습니다.

이 wiki 체크아웃합니다 관한 문서 객체 복사.

[Frequencyid) 는 다음과 같은 뜻이 있다. 객체에는 복사] (http://en.wikipedia.org/wiki/Object_copy # Copying_in_Java)

해설 (0)

예. 깊이형 복제본에 에서 객체에는 합니다.

해설 (1)

아래 코드를 추가 클래스에서 '와' 복제 가능

public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

= (유르클레스) '이' 클레오니도비치 유르클레소브ject.c론 ();

해설 (0)

이 기능은 없다. 가정 모델

class UserAccount{
   public int id;
   public String name;
}

첫 번째 추가

39, & # 39 ',' 컴파일하십시오 com.google.code.gson:gson:2.8.1& 데이터베이스에구성원을 app&gt gradle &; 동기화. 그럼

Gson gson = new Gson();
updateUser = gson.fromJson(gson.toJson(mUser),UserAccount.class);

이후 '임시' 키워드를 사용하여 액세스 수정자의 필드를 사용하여 제외할 수 있습니다.

  • Note:* 이건 미친 짓이야 "라고 언급하였다. # 39 도 사용할 수 없다 ',' 또는 '' It& 자바즈리얼리제이션 don& 추천합니까 복제 가능 # 39 의 속도가 느려지고 있는 셈이다. 쓰기 성능을 최적화하려면 복제본에 구성자를 [참조] [1].

같은 일이

class UserAccount{
        public int id;
        public String name;
        //empty constructor
        public UserAccount(){}
        //parameterize constructor
        public UserAccount(int id, String name) {
            this.id = id;
            this.name = name;
        }

        //copy constructor
        public UserAccount(UserAccount in){
            this(in.id,in.name);
        }
    }
  • 테스트 통계 중 90000 iteration:&lt br/>; 선 ' (그송.toj슨 (aO), 우저스카운트리클레스),' 는 808ms 그송.프롬제슨 우저스카운트 클론 = *

선 ',' 는 1ms 미만임 우저스카운트 클론할 = new 우저스카운트 (aO)

  • Conclusion:* 그슨 사용할 경우 이 미친 진실이며당신이 속도용 상사를 선호한다. 두 번째 복제본에 구성자를 사용을 원할 경우 품질.

발생기입니다 플러그인에는 의 코드를 사용할 수도 있습니다 복제본에 구성자를 안드로이드 스튜디오.

[1]: http://www.javapractices.com/topic/TopicAction.do? Id = 12

해설 (2)

39 의 here& 끝날 경우 clone () '' 제대로 된 설명도 필요 없습니다.

[Here. 클론 (Java method)] (http://en.wikipedia.org/wiki/Clone_% 28Java_method% 29)

해설 (0)

깊이형 클론한 유틸리티를 사용합니다.

SomeObjectType copy = new Cloner().deepClone(someObject);

이렇게 하면 모든 자바 객체를 깊이형 복제본에 체크아웃합니다 dell. https://github.com/kostaskougios/cloning

해설 (1)

깊이형 클론한 복제 가능 '' 인터페이스와 구현을 필요로 하는 답이 재정의을 clone () '이' 메서드입니다.

public class DummyBean implements Cloneable {

   private String dummy;

   public void setDummy(String dummy) {
      this.dummy = dummy;
   }

   public String getDummy() {
      return dummy;
   }

   @Override
   public Object clone() throws CloneNotSupportedException {
      DummyBean cloned = (DummyBean)super.clone();
      cloned.setDummy(cloned.getDummy());
      // the above is applicable in case of primitive member types, 
      // however, in case of non primitive types
      // cloned.setNonPrimitiveType(cloned.getNonPrimitiveType().clone());
      return cloned;
   }
}

이와 같이 선고하게 것입니다. '=' 도미빈 덤스워 두마리클로네 ();

해설 (1)

어떤 식으로든 객체에는 클론할 그렇게 할 수 있습니다. 비록 Java 는 클론한 메커니즘을 사용하는 경우에는 don& # 39, t, t # 39 don& 한다. Create a copy 를 사용할 수 있는 방법, 그리고 산아래의 복제본에 재동기화할:

dumtwo = dum.copy();

Here 은 좀 더 조언을 수행하기 위한 여러 가지 기술을 복사됩니다.

해설 (0)

불변 객체는 명시적으로 복사, 이외의 다른 외곽진입 수 있다 (no '세트' 또는 기타 테이터 메서드을). 문제는 이런 식으로 배반자들의 한번 해볼 수 있다. 불역성 갈수록 어려워지고 있는 것이 아니라, 다른 쪽 푸시합니다 오브젝트에도 큰 것이 작은 물건들을 로 분할 및 합성 일관된 방향으로 있습니다.

해설 (0)

(Http://x-stream.github.io/) 에서 함께 자동으로 스슬림 깊이형 복제본에 수 있습니다.

&gt. 스슬림 것은 단순한 XML 라이브러리를 직렬화할 객체에는 뒤로를 &gt. 다시.

추가해 프로젝트 (메이븐 사용하는 경우)


    com.thoughtworks.xstream
    xstream
    1.3.1                

그럼

DummyBean dum = new DummyBean();
dum.setDummy("foo");
DummyBean dumCopy = (DummyBean) XSTREAM.fromXML(XSTREAM.toXML(dum));

You have a 복제본에 구현하십시오 대체하십시오 필요 없이 모든 클론한 인터페이스입니다.

해설 (4)
class DB {
  private String dummy;

  public DB(DB one) {
    this.dummy = one.dummy; 
  }
}
해설 (0)

객체에는 전달하십시오 복사할지를 및 내려받습니다 객체에는 운영까지도:

private Object copyObject(Object objSource) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(objSource);
            oos.flush();
            oos.close();
            bos.close();
            byte[] byteData = bos.toByteArray();
            ByteArrayInputStream bais = new ByteArrayInputStream(byteData);
            try {
                objDest = new ObjectInputStream(bais).readObject();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return objDest;

    }

'지금' 를 원하는 객체에는 구문 분석을 오비에데스트.

즐거운 코딩!

해설 (0)
public class MyClass implements Cloneable {

private boolean myField= false;
// and other fields or objects

public MyClass (){}

@Override
public MyClass clone() throws CloneNotSupportedException {
   try
   {
       MyClass clonedMyClass = (MyClass)super.clone();
       // if you have custom object, then you need create a new one in here
       return clonedMyClass ;
   } catch (CloneNotSupportedException e) {
       e.printStackTrace();
       return new MyClass();
   }

  }
}

및 코드에서:

MyClass myClass = new MyClass();
// do some work with this object
MyClass clonedMyClass = myClass.clone();
해설 (1)

할 수 있습니다 '와' 복제 가능 '' 방법을 사용하여 구현하십시오 clone (); 그러나 이 방법을 사용하는 경우 '표준' & # 39 에 클론할 합니다 - 항상 객체에는 오버라이드합니다 clone () '의' 공개 객체에는 메서드입니다.

해설 (0)