基本类型拷贝:

克隆是针对于对象而言的,基本类型(boolean,char,byte,short,float,double.long)已久具备自身克隆的特性.

 

    int x=1;
        int y=x;
        System.out.println(x);//1
        System.out.println(y);//1
        y=2;
        System.out.println(x);//1
        System.out.println(y);//2

 

JVM实现拷贝的目的:

大家先思考一个问题,为什么需要克隆对象?直接 new 一个对象不行吗?

  答案是:克隆的对象可能包含一些已经修改过的属性,而 new 出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的 “状态” 就靠 clone 方法了。那么我把这个对象的临时属性一个一个的赋值给我新 new 的对象不也行嘛?

    可以是可以,但是一来麻烦不说,二来,大家通过上面的源码都发现了 clone 是一个 native 方法,就是快啊,在底层实现的

引用的拷贝

1 //引用拷贝
2     private static void copyReferenceObject(){
3         Person p = new Person(23, "zhang");
4         Person p1 = p;
5         System.out.println(p);
6         System.out.println(p1);
7     }

 

这里打印的结果: 
Person@3654919e 
Person@3654919e 
可以看到,打印的结果是一样的,也就是说,二者的引用是同一个对象,并没有创建出一个新的对象。因此要区分引用拷贝和对象拷贝的区别,下面要介绍的就是对象拷贝。 

浅拷贝

  • 如果pojo中存在的是基本数据类型 ,String 除外 ,实现Cloneable 覆写Clone 方法 这个就是浅拷贝

- code 

 1 package core.java.deeporshoawcopy;
 2 
 3 /**
 4  * @author DGW-PC
 5  * @date 2018年6月7日
 6  * @see 验证   浅拷贝  一般要求实体类使用包装类型 对于深拷贝 类中存在对其他类的引用,也需要实现cloneable接口
 7  */
 8 
 9 class Person implements Cloneable{
10     private String name;
11     private Integer age;
12     public String getName() {
13         return name;
14     }
15     public void setName(String name) {
16         this.name = name;
17     }
18     public Integer getAge() {
19         return age;
20     }
21     public void setAge(Integer age) {
22         this.age = age;
23     }
24     @Override
25     protected Object clone() throws CloneNotSupportedException  {
26         /*Person p=null;
27         try{
28             p=(Person) super.clone();
29         }catch (CloneNotSupportedException e) {
30         }*/
31         return super.clone();
32     }
33 }
34 
35 public class Base {
36     
37      public static void main(String[] args) throws CloneNotSupportedException {
38         Person person = new Person();
39         person.setName("a");
40         person.setAge(12);
41         Person per1=(Person) person.clone();
42         per1.setName("b");
43         per1.setAge(14);;
44         System.out.println(person.getName()+" "+person.getAge().hashCode(0));
45         System.out.println(per1.getName()+" "+per1.getAge());
46     }
47 
48 }

 内存图:

Java中对象拷贝的两种方式

 

 

 

深拷贝

- 如果你的POJO 存在的不是基本上数据类型,可以是自己定义类型,也可以其他包提供的类型 这里以java 提供的Data 的为例子 可以看下面的代码 自身实现clone 方法 你在涉及到使用拷贝的时候一定要注意别的包提供的类是否出现了问题

 1  /**
 2      * Return a copy of this object.
 3      */
 4     public Object clone() {
 5         Date d = null;
 6         try {
 7             d = (Date)super.clone();
 8             if (cdate != null) {
 9                 d.cdate = (BaseCalendar.Date) cdate.clone();
10             }
11         } catch (CloneNotSupportedException e) {} // Won't happen
12         return d;
13     }

- 下面介绍一下基本深拷贝的代码 很短 : 你一定主要 主类包装了多少其他的引用类型的其他类,那么其他必须都要实现Cloneable 接口 以及clone (保护方法) 方法

方法原型:

仔细一看,它还是一个 native 方法,大家都知道 native 方法是非 Java 语言实现的代码,供 Java 程序调用的,

因为 Java 程序是运行在 JVM 虚拟机上面的,要想访问到比较底层的与操作系统相关的就没办法了,只能由靠近操作系统的语言来实现

 

1/*
2Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object.
3The general intent is that, for any object x, the expression:
41) x.clone() != x will be true
52) x.clone().getClass() == x.getClass() will be true, but these are not absolute requirements.
63) x.clone().equals(x) will be true, this is not an absolute requirement.
7*/
8protected native Object clone() throws CloneNotSupportedException;

 

 

 

需要满足的条件:

  对于任何对象x,表达式:

  • 1)x.clone()!= x将为真
  • 2)x.clone()。getClass()== x.getClass()为true,但这不是绝对要求。
  • 3)x.clone()。equals(x)将为true,这不是绝对要求。

 

具体代码:

 1 package core.java.deeporshoawcopy;
 2 
 3 
 4 /**
 5  * @author DGW-PC
 6  * @date 2018年6月7日
 7  * @see 实现序列化  深拷贝
 8  */
 9 
10 class Dog implements Cloneable{
11     private String name;
12 
13     public String getName() {
14         return name;
15     }
16 
17     public void setName(String name) {
18         this.name = name;
19     }
20     @Override
21     protected Object clone() throws CloneNotSupportedException {
22         return super.clone();
23     }
24 }
25 class User implements Cloneable{
26     private String name;
27     private Dog dog;
28     public String getName() {
29         return name;
30     }
31     public void setName(String name) {
32         this.name = name;
33     }
34     public Dog getDog() {
35         return dog;
36     }
37     public void setDog(Dog dog) {
38         this.dog = dog;
39     }
40     @Override
41     protected Object clone() throws CloneNotSupportedException {
42         User u=(User) super.clone();
43         u.dog=(Dog) dog.clone(); //多个需要在全部把关系搞清楚
44         return u;
45     }
46 }
47 
48 public class ObjCloner {
49         public static void main(String[] args) throws CloneNotSupportedException {
50             Dog dog = new Dog();
51             dog.setName("田园犬");
52             User user = new User();
53             user.setDog(dog);
54             user.setName("王二");
55             User user1=(User) user.clone();
56             user1.setName("张三");
57             Dog dog2 = new Dog();
58             dog2.setName("德国牧羊犬");
59             user1.setDog(dog2);
60             System.out.println(user.getName()+"养了"+ user.getDog().getName());
61             System.out.println(user1.getName()+"养了"+ user1.getDog().getName());
62         }
63 }

 

结果:

Java中对象拷贝的两种方式

 

类组合形式下深拷贝

  1 class Car implements Cloneable{
  2     String name;
  3 
  4     public Car(String name) {
  5         this.name = name;
  6     }
  7     @Override
  8     protected Object clone()  {
  9         Car car=null;
 10         try {
 11             car=(Car) super.clone();
 12         } catch (CloneNotSupportedException e) {
 13             e.printStackTrace();
 14         }
 15         return car;
 16     }
 17     @Override
 18     public String toString() {
 19         return "Car [name=" + name + "]";
 20     }
 21 }
 22 class Home implements Cloneable{
 23     String name;
 24     public Home(String name) {
 25         this.name = name;
 26     }
 27     @Override
 28     protected Object clone()  {
 29         Home home=null;
 30         try {
 31             home=(Home) super.clone();
 32         } catch (CloneNotSupportedException e) {
 33             e.printStackTrace();
 34         }
 35         return home;
 36     }
 37     @Override
 38     public String toString() {
 39         return "Home [name=" + name + "]";
 40     }
 41 }
 42 class Wife implements Cloneable{
 43     String name;
 44     public Wife(String name) {
 45         this.name = name;
 46     }
 47     @Override
 48     protected Object clone()  {
 49         Wife wife=null;
 50         try {
 51             wife=(Wife) super.clone();
 52         } catch (CloneNotSupportedException e) {
 53             e.printStackTrace();
 54         }
 55         return wife;
 56     }
 57     @Override
 58     public String toString() {
 59         return "Wife [name=" + name + "]";
 60     }
 61 }
 62 class Person implements Cloneable{
 63     String name;
 64     Car car;
 65     Home home;
 66     Wife wife;
 67     public Person(String name, Car car, Home home, Wife wife) {
 68         super();
 69         this.name = name;
 70         this.car = car;
 71         this.home = home;
 72         this.wife = wife;
 73     }
 74     @Override
 75     public String toString() {
 76         return "Person [name=" + name + ", car=" + car + ", home=" + home + ", wife=" + wife + "]";
 77     }
 78     @Override
 79     protected Object clone()  {
 80         Person person=null;
 81         try {
 82             person=(Person) super.clone();
 83         } catch (CloneNotSupportedException e) {
 84             e.printStackTrace();
 85         }
 86         person.car=(Car) this.car.clone();
 87         person.home=(Home) this.home.clone();
 88         person.wife=(Wife) this.wife.clone();
 89         return person;
 90     }
 91     
 92 }
 93 
 94 public class Test2 {
 95     public static void main(String[] args) {
 96         Person person = new Person("Tom", new Car("bmw"), new Home("一环以内"), new Wife("intkk"));
 97         //Person person1=person;
 98         Person person1 = (Person) person.clone();
 99         System.out.println(person);
100         System.out.println(person1);
101         person1.name="Jerry";
102         person1.home= new Home("帝国");
103         person1.car=new Car("五菱骨灰盒");
104         System.out.println(person);
105         System.out.println(person1);
106     }
107 }
View Code

相关文章: