복붙노트

[SPRING] clone 또는 BeanUtils.copyProperties를 사용해야하며 이유는 무엇입니까?

SPRING

clone 또는 BeanUtils.copyProperties를 사용해야하며 이유는 무엇입니까?

BeanUtils.copyProperties는 객체의 복제본을 만드는 것처럼 보입니다. 이 경우, Cloneable 인터페이스를 구현하는 것에 대한 염려가있는 것은 무엇입니까? (변경할 수있는 객체 만이 복사 가능한 참조가 복사 된 새로운 객체 인 경우) 무엇이 가장 좋고 그 이유는 무엇입니까?

어제는 cloneable을 구현하고 나서 String / Primative이 아닌 요소에 대한 자체 수정을 제공해야한다는 것을 깨달았습니다. 나는 지금 내가 사용하고있는 BeanUtils.copyProperties에 대한 정보를 얻었습니다. 두 구현 모두 비슷한 기능을 제공하는 것 같습니다.

감사

해결법

  1. ==============================

    1.Josh Bloch는 복제 생성자가 근본적으로 결함이있어 복사 생성자를 선호한다고 주장하면서 (제공 한 것을 포함하여) 꽤 좋은 주장을 제시합니다. 여길 봐.

    Josh Bloch는 복제 생성자가 근본적으로 결함이있어 복사 생성자를 선호한다고 주장하면서 (제공 한 것을 포함하여) 꽤 좋은 주장을 제시합니다. 여길 봐.

    필자는 아직 불변 개체를 복사하는 실제적인 사용 사례를 접하지 못했다. 특정 이유로 개체를 복사하고 있습니다. 아마도 일부 변경 가능한 개체를 단일 트랜잭션으로 분리하여 처리 단위로 격리하고 처리 단위가 완료 될 때까지 개체를 변경할 수는 없습니다. 그들은 이미 불변이라면 참조는 복사본만큼 좋다.

    BeanUtils.copyProperties는 지원할 클래스를 변경하지 않고도 복사하기가 덜 복잡하며 객체 합성시 고유 한 유연성을 제공합니다.

    즉, copyProperties는 항상 하나의 크기에 맞는 것은 아닙니다. 특수한 생성자를 가지고 있지만 여전히 변경 가능한 유형을 포함하는 객체를 지원해야 할 수도 있습니다. 개체는 내부 메서드 또는 생성자가 예외를 해결하도록 지원하거나 특정 형식을 복사하기 위해 외부 도구에 등록 할 수 있지만 clone ()이 수행 할 수있는 일부 위치에는 연결할 수 없습니다. 좋습니다.하지만 여전히 한계가 있습니다.

  2. ==============================

    2.BeanUtils는 객체의 필드 값을 다른 객체로 단순히 복사하는 표준 복제품보다 융통성이 있습니다. 복제 메서드는 같은 클래스의 빈에서 필드를 복사하지만 BeanUtils는 동일한 특성 이름을 가진 서로 다른 클래스의 인스턴스 두 개에 대해이를 수행 할 수 있습니다.

    BeanUtils는 객체의 필드 값을 다른 객체로 단순히 복사하는 표준 복제품보다 융통성이 있습니다. 복제 메서드는 같은 클래스의 빈에서 필드를 복사하지만 BeanUtils는 동일한 특성 이름을 가진 서로 다른 클래스의 인스턴스 두 개에 대해이를 수행 할 수 있습니다.

    예를 들어, 필드 A와 B가 동일한 필드 java.util.Date 날짜를 갖는 Bean A를 가지고 있다고 가정 해 봅시다. BeanUtils를 사용하면 문자열 값을 복사하여 DateFormat을 사용하여 자동으로 날짜로 변환 할 수 있습니다.

    필자는 SOAP 객체를 동일한 데이터 유형을 가지고 있지 않은 Hibernate 객체로 변환하는데 사용했다.

  3. ==============================

    3.나는 당신이 깊은 사본을 찾고 있다고 생각합니다. 당신은 util 클래스에서 아래의 메소드를 가질 수 있고 어떤 종류의 객체에서도 사용할 수 있습니다.

    나는 당신이 깊은 사본을 찾고 있다고 생각합니다. 당신은 util 클래스에서 아래의 메소드를 가질 수 있고 어떤 종류의 객체에서도 사용할 수 있습니다.

    public static <T extends Serializable> T copy(T input) {
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(input);
            oos.flush();
    
            byte[] bytes = baos.toByteArray();
            bis = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bis);
            Object result = ois.readObject();
            return (T) result;
        } catch (IOException e) {
            throw new IllegalArgumentException("Object can't be copied", e);
        } catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("Unable to reconstruct serialized object due to invalid class definition", e);
        } finally {
            closeQuietly(oos);
            closeQuietly(baos);
            closeQuietly(bis);
            closeQuietly(ois);
        }
    }
    
  4. ==============================

    4.귀하의 질문에 나는 당신이 개체의 깊은 사본이 필요하다고 생각합니다. 이 경우 복제 방법은 오라클 워드 프로세서에서 이미 지정되어 있으므로 연관된 객체의 단순 복사본을 제공하므로 복제 방법을 사용하지 마십시오. 그리고 BeanUtils.copyProperties API에 대한 충분한 아이디어가 없습니다. 아래에는 딥 카피의 간단한 데모가 있습니다. 여기서 나는 원시 배열을 복사하고있다. 모든 유형의 객체로이 코드를 시도 할 수 있습니다.

    귀하의 질문에 나는 당신이 개체의 깊은 사본이 필요하다고 생각합니다. 이 경우 복제 방법은 오라클 워드 프로세서에서 이미 지정되어 있으므로 연관된 객체의 단순 복사본을 제공하므로 복제 방법을 사용하지 마십시오. 그리고 BeanUtils.copyProperties API에 대한 충분한 아이디어가 없습니다. 아래에는 딥 카피의 간단한 데모가 있습니다. 여기서 나는 원시 배열을 복사하고있다. 모든 유형의 객체로이 코드를 시도 할 수 있습니다.

    import java.io.*;
    class ArrayDeepCopy 
    {
        ByteArrayOutputStream baos;
        ByteArrayInputStream bins;
        public void saveState(Object obj)throws Exception //saving the stream of bytes of object to `ObjectOutputStream`.
        {
            baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            oos.close();
        }
        public int[][] readState()throws Exception //reading the state back to object using `ObjectInputStream`
        {
            bins = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream oins = new ObjectInputStream(bins);
            Object obj = oins.readObject();
            oins.close();
            return (int[][])obj;
        }
        public static void main(String[] args) throws Exception
        {
            int arr[][]= {
                            {1,2,3},
                            {4,5,7}
                        };
            ArrayDeepCopy ars = new ArrayDeepCopy();
            System.out.println("Saving state...");
            ars.saveState(arr);
            System.out.println("State saved..");
            System.out.println("Retrieving state..");
            int j[][] = ars.readState();
            System.out.println("State retrieved..And the retrieved array is:");
            for (int i =0 ; i < j.length ; i++ )
            {
                for (int k = 0 ; k < j[i].length ; k++)
                {
                    System.out.print(j[i][k]+"\t");
                }
                System.out.print("\n");
            }
    
        }
    }
    
  5. ==============================

    5.복제본은 객체의 단순 복사본을 만들고 복제 객체는 항상 원래의 것과 같은 클래스입니다. 비공개 또는 비공개 된 모든 필드가 복사됩니다.

    복제본은 객체의 단순 복사본을 만들고 복제 객체는 항상 원래의 것과 같은 클래스입니다. 비공개 또는 비공개 된 모든 필드가 복사됩니다.

    BeanUtils.copyProperties API 특성 이름이 동일한 모든 경우에 대해 원 본 bean에서 대상 Bean으로 특성 값을 복사하십시오.

    나에게이 두 개념은 거의 공통점이 없다.

  6. ==============================

    6.복제는 사용자가 수행합니다. 복제하려는 인스턴스에 다른 인스턴스의 참조가 포함되어 있으면 복제 코드를 작성해야합니다. 인스턴스에 다른 인스턴스에 대한 참조 체인이 있으면 어떻게됩니까? 따라서 스스로 복제하는 경우 작은 세부 사항을 놓칠 가능성이 있습니다.

    복제는 사용자가 수행합니다. 복제하려는 인스턴스에 다른 인스턴스의 참조가 포함되어 있으면 복제 코드를 작성해야합니다. 인스턴스에 다른 인스턴스에 대한 참조 체인이 있으면 어떻게됩니까? 따라서 스스로 복제하는 경우 작은 세부 사항을 놓칠 가능성이 있습니다.

    BeanUtils.copyProperties는 다른 모든 것을 스스로 처리합니다. 그것은 당신의 노력을 줄여줍니다.

  7. from https://stackoverflow.com/questions/15542504/should-we-use-clone-or-beanutils-copyproperties-and-why by cc-by-sa and MIT license