zoukankan      html  css  js  c++  java
  • Java和PHP中的浅克隆和深克隆

    在Java中,需要在被克隆的类上实现Cloneable接口,重写clone方法即可。浅克隆只能克隆类中基本数据类型以及String类型属性,不能克隆类中的引用类型属性。导致两个类中,同一个引用类型属性指向同一个引用对象。

    如果在类的引用类型属性对应的类中,实现Cloneable接口,重写clone方法,就可以实现深拷贝

    package fengliang.firstjava;
    
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    
    class Employee implements Cloneable {
        protected String name;
        protected double salary;
        protected int id = assignId();
        protected static int nextId = 1;
        protected LocalDate hireDay;
    
        public Employee() {
        }
    
        public Employee(String var1, double var2, String var4) {
            this.name = var1;
            this.salary = var2;
            this.hireDay = LocalDate.parse(var4);
        }
    
        public Employee(String var1, double var2) {
            this.name = var1;
            this.salary = var2;
        }
    
        public String getHireDay() {
            return this.hireDay.format(DateTimeFormatter.ofPattern("y-MM-dd"));
        }
    
        public String getHireDay(String var1) {
            return this.hireDay.format(DateTimeFormatter.ofPattern(var1));
        }
    
        public String getName() {
            return this.name;
        }
    
        public final Employee setName(String var1) {
            this.name = var1;
            return this;
        }
    
        public final Employee setName() {
            return this;
        }
    
        public int getId() {
            return this.id;
        }
    
        protected static int assignId() {
            return nextId++;
        }
    
        public Employee clone() {
            Employee var1 = null;
    
            try {
                var1 = (Employee)super.clone();
            } catch (CloneNotSupportedException var3) {
                var3.printStackTrace();
            }
    
            return var1;
        }
    }
    
    class ShadowCopy <T extends Employee> implements Cloneable {
    
        private T employee;
        private String cardId;
    
        ShadowCopy() {}
        ShadowCopy(T employee, String cardId) {
            this.employee = employee;
            this.cardId = cardId;
        }
    
        public T getEmployee() {
            return employee;
        }
    
        public String getCardId() {
            return cardId;
        }
    
        public ShadowCopy<T> setEmployee(T employee) {
            this.employee = employee;
            return  this;
        }
    
        public ShadowCopy<T> setCardId(String cardId) {
            this.cardId = cardId;
            return  this;
        }
        
        //注意这里,浅拷贝
        @Override
        public ShadowCopy<T> clone() {
            try {
                return (ShadowCopy<T>) super.clone();
            } catch (CloneNotSupportedException exception) {
                return this;
            }
        }
    }
    
    class DeepCopy<T extends Employee> extends ShadowCopy<T> {
    
        DeepCopy(T employee, String cardId) {
            super(employee, cardId);
        }
    
        //注意这里,深拷贝。当注释clone.setEmployee((T)this.getEmployee().clone());后,它也是浅复制
        @Override
        public DeepCopy<T> clone() {
            DeepCopy<T> clone =  (DeepCopy<T>) super.clone();
            clone.setEmployee((T)this.getEmployee().clone());
            return clone;
        }
    }
    
    public class CloneTest {
        public static void main(String[] args) {
            Employee employee = new Employee("张三", 12);
    
            System.out.println("-------------------------------浅拷贝-------------------------------");
            ShadowCopy<Employee> shadowCopyObject = new ShadowCopy<Employee>(employee, "00001");
            ShadowCopy<Employee> clonedShadowCopyObject = shadowCopyObject.clone();
            clonedShadowCopyObject.setCardId("李四"+shadowCopyObject.getCardId()).getEmployee().setName("李四");
            System.out.println("原始shadowCopyObject对象中,Employee对象的name属性值为:"+shadowCopyObject.getEmployee().getName());
            System.out.println("clonedShadowCopyObject对象中,Employee对象的name属性值为:"+clonedShadowCopyObject.getEmployee().getName());
            System.out.println("原始shadowCopyObject对象中,CardId属性值为:"+shadowCopyObject.getCardId());
            System.out.println("clonedShadowCopyObject对象中,CardId属性值为:"+clonedShadowCopyObject.getCardId());
    
            System.out.println();
    
            System.out.println("-------------------------------深拷贝-------------------------------");
            Employee deepCopyEmployee = new Employee("王五", 13);
            DeepCopy<Employee> deepCopyObject = new DeepCopy<>(deepCopyEmployee, "00002");
            DeepCopy<Employee> clonedDeepCopyObject = deepCopyObject.clone();
            clonedDeepCopyObject.setCardId("赵六"+deepCopyObject.getCardId()).getEmployee().setName("赵六");
            System.out.println("原始deepCopyObject对象中,Employee对象的name属性值为:"+deepCopyObject.getEmployee().getName());
            System.out.println("clonedDeepCopyObject对象中,Employee对象的name属性值为:"+clonedDeepCopyObject.getEmployee().getName());
            System.out.println("原始deepCopyObject对象中,CardId属性值为:"+deepCopyObject.getCardId());
            System.out.println("clonedDeepCopyObject对象中,CardId属性值为:"+clonedDeepCopyObject.getCardId());
        }
    }
    View Code

    在PHP中,使用clone关键字实现浅克隆,如果要实现深克隆,需要在类中实现__clone魔术方法

    class Employee{
        protected $name;
        protected $id;
        protected static $nextId = 1;
    
        public function __construct(String $name)
        {
            $this->id = self::assignId();
            $this->name = $name;
    
        }
    
        protected static function assignId() : int
        {
            return self::$nextId++;
        }
    
        /**
         * @return String
         */
        public function getName(): string
        {
            return $this->name;
        }
    
        /**
         * @param String $name
         */
        public function setName(string $name) : Employee
        {
            $this->name = $name;
            return $this;
        }
    
    }
    
    class ShadowClone {
        protected $employee;
    
        protected $cardId;
    
        public function __construct(Employee $employee, String $cardId)
        {
            $this->employee = $employee;
            $this->cardId = $cardId;
        }
    
        public function getCardId() : int {
            return $this->cardId;
        }
    
        /**
         * @return Employee
         */
        public function getEmployee(): Employee
        {
            return $this->employee;
        }
    }
    
    class DeepClone extends ShadowClone {
        
        function __clone()
        {
            //去掉这一行,就变成类浅克隆
            $this->employee = clone $this->employee;
        }
    }
    
    $employee = new Employee('张三');
    $deepClone = new DeepClone($employee, '00001');
    $cloneDeepClone = clone $deepClone;
    $cloneDeepClone->getEmployee()->setName('李四');
    echo $deepClone->getEmployee()->getName()."
    ";
    echo $cloneDeepClone->getEmployee()->getName();
    View Code

     

  • 相关阅读:
    web.config中的customErrors标记的用法
    算法系列15天速成[索引]
    log4net的简单使用
    Cookie帮助类
    ASPxTreeList及ASPxGridView使用
    javascript获取页面中的位置
    如何部署windows服务?
    基于T4模板引擎生成静态网站(CMS)
    SqlServer实现递归查询
    安卓(AndRoid)开发环境搭建之HelloWord
  • 原文地址:https://www.cnblogs.com/fengliang/p/14121667.html
Copyright © 2011-2022 走看看