>  기사  >  Java  >  Java Cloneable 인터페이스의 전체 복사 및 얕은 복사 방법

Java Cloneable 인터페이스의 전체 복사 및 얕은 복사 방법

PHPz
PHPz앞으로
2023-04-28 08:49:131182검색

    복제 가능한 인터페이스 소스 코드

    복제 가능한 인터페이스:

    이 인터페이스를 구현하는 클래스 - clone() 메서드를 합법적으로 호출할 수 있다고 추론할 수 있음 - 클래스 인스턴스 구현: 속성 대 속성 복사 중. java.lang.Object

    클래스가 Cloneable 인터페이스를 구현하지 않으면 clone() 메서드가 호출될 때 CloneNotSupportedException이 발생합니다.

    일반적으로 Cloneable 인터페이스를 구현하는

    하위 클래스는 공용 액세스로 clone() 메소드를 재정의해야 합니다. (java.Object 클래스의 clone 메소드는 보호 유형이지만)

    Cloneable 인터페이스는 그렇지 않다는 점을 인식해야 합니다. include clone() 메소드이므로 Cloneable 인터페이스만 구현하면 정상적으로 객체를 복제할 수 없습니다

    [이유: 반사적으로 clone 메소드를 호출하더라도 성공한다는 보장은 없습니다]&mdash ;—개인적인 이해는:

    Clone() 메서드를 재정의할지 여부 또는 "shallow copy 및 deep copy" 문제로 인해 발생합니다.

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    얕은 복사 사례

    Pet 클래스 정의

    참고: Pet 클래스는 Cloneable 인터페이스를 구현하지만 Clone() 메서드를 재정의하지 않습니다(분명히: Pet 클래스에는 현재 개체를 복제하는 기능이 없습니다). ).

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    Person 클래스 정의

    참고: Person 클래스는 Cloneable 인터페이스를 구현하고 Clone() 메서드도 재정의합니다. 그렇다면 Person 클래스에는 객체를 복제하는 기능이 있습니까? (얕은 복사 문제로 인해 이 객체 복제 기능은 불완전하고 결함이 있는 것으로 간주됩니다.)

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    얕은 복사 문제 - 코드 테스트

    왜 이렇게 말합니까: 현재 Person 클래스의 객체 복제 기능이 불완전하고 결함이 있습니까? 왜냐하면 이때 Person 객체를 통해 clone() 메소드가 호출되어 객체가 복제되면 해당 구성원 속성인 pet(Pet 클래스의 객체) 값의 복제는 단지 메모리 주소의 단순한 복사본이기 때문입니다. 힙 영역에서.

    즉, 직설적으로 말하면 Person 개체의 pet 속성 값과 복제된 개체는 동일한 힙 영역 메모리를 공유합니다. 문제는 명백합니다. 복제된 객체의 pet 속성이 설정되면 원본 Person 객체의 pet 속성 값에 분명히 영향을 미칩니다.

    코드 시연은 다음과 같습니다.

      //methods
        public static void main(String[] args) throws CloneNotSupportedException {
            testPerson();
        }
        public static void testPerson() throws CloneNotSupportedException {
            Person p=new Person("张三",14,new Pet("小黑"));
            System.out.println(p);
            Person clone = (Person)p.clone();
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println(p.getPet()==clone.getPet());
            System.out.println("************");
            clone.setAge(15);
            System.out.println(p);
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println("************");
            clone.getPet().setName("小黄");
            System.out.println(p);
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println(p.getPet()==clone.getPet());
        }

    Java Cloneable 인터페이스의 전체 복사 및 얕은 복사 방법

    Deep Copy 사례

    그럼 Deep Copy를 어떻게 구현할까요? 위 사례에서 핵심은 주석 처리된 코드 줄에 있습니다.

    Pet 클래스는 clone() 메소드를 재정의합니다

    Java Cloneable 인터페이스의 전체 복사 및 얕은 복사 방법

    Person의 clone() 메소드는 Pet의 clone 메소드를 호출합니다.

    Java Cloneable 인터페이스의 전체 복사 및 얕은 복사 방법

    Shallow Copy 문제 해결 - Deep Copy 코드 테스트

    테스트 코드는 변경되지 않고 다시 실행됩니다. :

    Java Cloneable 인터페이스의 전체 복사 및 얕은 복사 방법

    위 내용은 Java Cloneable 인터페이스의 전체 복사 및 얕은 복사 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제