java:浅复制与深复制

java:浅复制与深复制

八种原始数据类型(int,boolean,char,byte,short,float,double.long)的复制
       int apples = 5; 
       int pears = apples; 

万类之王Object有11个方法,有两个protected的方法,其中一个为clone方法。
该方法的签名是:protected native Object clone() throws CloneNotSupportedException;
因为每个类直接或间接的父类都是Object,因此它们都含有clone()方法,但是因为该方法是protected,所以都不能在类外进行访问。要想对一个对象进行复制,就需要对clone方法覆盖。
一般步骤是(浅复制):
       1. 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常) 该接口为标记接口(不含任何方法)
       2. 覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象,(native为本地方法)
       class Student implements Cloneable{ 
           private int number; 
           public int getNumber() { 
               return number; 
           } 
           public void setNumber(int number) { 
               this.number = number; 
           } 
            
           @Override 
           public Object clone() { 
               Student stu = null; 
               try{ 
                   stu = (Student)super.clone(); 
               }catch(CloneNotSupportedException e) { 
                   e.printStackTrace(); 
               } 
               return stu; 
           } 
       } 
       public class Test {           
           public static void main(String args[]) {                
               Student stu1 = new Student(); 
               stu1.setNumber(12345); 
               Student stu2 = (Student)stu1.clone(); 
                
               System.out.println("学生1:" + stu1.getNumber()); 
               System.out.println("学生2:" + stu2.getNumber()); 
                
               stu2.setNumber(54321); 
            
               System.out.println("学生1:" + stu1.getNumber()); 
               System.out.println("学生2:" + stu2.getNumber()); 
                System.out.println(stu1 == stu2); 
           } 
       } 
       输出结果为:
           学生1:12345 
           学生2:12345 
       
           学生1:12345 
           学生2:54321 

            false

深复制:
       class Address implements Cloneable { 
           private String add; 
           public String getAdd() { 
               return add; 
           } 
           public void setAdd(String add) { 
               this.add = add; 
           } 
            
           @Override 
           public Object clone() { 
               Address addr = null; 
               try{ 
                   addr = (Address)super.clone(); 
               }catch(CloneNotSupportedException e) { 
                   e.printStackTrace(); 
               } 
               return addr; 
           } 
       } 
       class Student implements Cloneable{ 
           private int number; 
           private Address addr; 
            
           public Address getAddr() { 
               return addr; 
           } 
           public void setAddr(Address addr) { 
               this.addr = addr; 
           } 
           public int getNumber() { 
               return number; 
           } 
           public void setNumber(int number) { 
               this.number = number; 
           } 
            
           @Override 
           public Object clone() { 
               Student stu = null; 
               try{ 
                   stu = (Student)super.clone();   //浅复制  
               }catch(CloneNotSupportedException e) { 
                   e.printStackTrace(); 
               } 
               stu.addr = (Address)addr.clone();   //深度复制  
               return stu; 
           } 
       } 
       public class Test {          
           public static void main(String args[]) {                
               Address addr = new Address(); 
               addr.setAdd("杭州市"); 
               Student stu1 = new Student(); 
               stu1.setNumber(123); 
               stu1.setAddr(addr); 
                
               Student stu2 = (Student)stu1.clone(); 
                
               System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd()); 
               System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd()); 
                
               addr.setAdd("西湖区"); 
                
               System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd()); 
               System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd()); 
           } 
       } 
       输出结果为:
            学生1:123,地址:杭州市 
            学生2:123,地址:杭州市 
       
            学生1:123,地址:西湖区 
            学生2:123,地址:杭州市

总结:
       浅拷贝是指在拷贝对象时,对于基本数据类型的变量会重新复制一份,而对于引用类型的变量只是对引用进行拷贝,没有对引用指向的对象进行拷贝。而深拷贝是指在拷贝对象时,同时会对引用指向的对象进行拷贝。区别就在于是否对 对象中的引用变量所指向的对象进行拷贝。

最后我们可以看看API里其中一个实现了clone方法的类:
java.util.Date(该类其实也属于深度复制。):
/**
* Return a copy of this object.
*/ 
public Object clone() { 
    Date d = null; 
    try { 
        d = (Date)super.clone(); 
        if (cdate != null) { 
            d.cdate = (BaseCalendar.Date) cdate.clone(); 
        } 
    } catch (CloneNotSupportedException e) {
// Won't happen
    }   
    return d; 

猜你喜欢

转载自blog.csdn.net/qq_29229567/article/details/80562101