服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|JavaScript|易语言|

服务器之家 - 编程语言 - Java教程 - Java实现克隆的三种方式实例总结

Java实现克隆的三种方式实例总结

2021-05-27 13:40疯狂1024 Java教程

这篇文章主要介绍了Java实现克隆的三种方式,结合实例形式总结分析了java浅复制、深复制以及使用serializable实现深复制的相关操作技巧,需要的朋友可以参考下

本文实例讲述了java实现克隆的三种方式。分享给大家供大家参考,具体如下:

1、浅复制(浅克隆)这种浅复制,其实也就是把被复制的这个对象的一些变量值拿过来了。最后生成student2还是一个新的对象。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class clonetest1
{
  public static void main(string[] args) throws exception
  {
    student1 student = new student1();
    student.setage(24);
    student.setname("niesong");
    student1 student2 = (student1)student.clone();
    //这个是调用下面的那个方法,然后把这个这个对象clone到student
    system.out.println("age:" + student2.getage() + " " + "name:" + student2.getname());
    system.out.println("---------------------");
    student2.setage(23);
    //克隆后得到的是一个新的对象,所以重新写的是student2这个对象的值
    system.out.println(student.getage());
    system.out.println(student2.getage());
  }
}
//克隆的对象必须实现cloneable这个接口,而且需要重写clone方法
class student1 implements cloneable
{
  private int age;
  //定义为private说明这个成员变量只能被被当前类中访问,如果外部需要获得,那么就只能通过getage方法进行获取
  private string name;
  public int getage()
  {
    return age;
  }
  public void setage(int age)
  {
    this.age = age;
  }
  public string getname()
  {
    return name;
  }
  public void setname(string name)
  {
    this.name = name;
  }
  @override
  public object clone() throws clonenotsupportedexception
  {
    object object = super.clone();
    return object;
  }
}

运行结果:

Java实现克隆的三种方式实例总结

2、深复制(情况1使用的是在克隆的时候手动进行深克隆)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public class clonetest2
{
  public static void main(string[] args) throws exception
  {
    teacher teacher = new teacher();
    teacher.setage(40);
    teacher.setname("teacher zhang");
    student2 student2 = new student2();
    student2.setage(14);
    student2.setname("lisi");
    student2.setteacher(teacher);
    student2 student3 = (student2)student2.clone();
    //这里是深复制,所以这时候student2中的teacher就是teacher这个对象的一个复制,就和student3是student2的一个复制
    //所以下面teacher.setname只是对他原来的这个对象更改,但是复制的那个并没有更改
    system.out.println(student3.getage());
    system.out.println(student3.getname());
    system.out.println(student3.getteacher().getage());
    teacher.setname("teacher niesong");//不会又任何影响
    system.out.println(student3.getteacher().getname());
  }
}
class student2 implements cloneable
{
  private int age;
  private string name;
  private teacher teacher;
  public int getage()
  {
    return age;
  }
  public void setage(int age)
  {
    this.age = age;
  }
  public string getname()
  {
    return name;
  }
  public void setname(string name)
  {
    this.name = name;
  }
  public teacher getteacher()
  {
    return teacher;
  }
  public void setteacher(teacher teacher)
  {
    this.teacher = teacher;
  }
  @override
  public object clone() throws clonenotsupportedexception
  {
    //这一步返回的这个student2还只是一个浅克隆,
    student2 student2 = (student2)super.clone();
    //然后克隆的过程中获得这个克隆的student2,然后调用这个getteacher这个方方法得到这个teacher对象。然后实现克隆。在设置到这个student2中的teacher。
    //这样实现了双层克隆使得那个teacher对象也得到了复制。
    student2.setteacher((teacher)student2.getteacher().clone());
    //双层克隆使得那个teacher对象也得到了复制
    return student2;
  }
}
class teacher implements cloneable
{
  private int age;
  private string name;
  public int getage()
  {
    return age;
  }
  public void setage(int age)
  {
    this.age = age;
  }
  public string getname()
  {
    return name;
  }
  public void setname(string name)
  {
    this.name = name;
  }
  @override
  public object clone() throws clonenotsupportedexception
  {
    return super.clone();
  }
}

运行结果:

Java实现克隆的三种方式实例总结

3、利用serializable实现深复制(这个是利用serializable,利用序列化的方式来实现深复制(深克隆),在其中利用了io流的方式将这个对象写到io流里面,然后在从io流里面读取,这样就实现了一个复制,然后实现序列化的这个会将引用的那个对象也一并进行深复制,这样就实现了这个机制,同时在io里面读取数据的时候还使用了装饰者模式)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import java.io.bytearrayinputstream;
import java.io.bytearrayoutputstream;
import java.io.objectinputstream;
import java.io.objectoutputstream;
import java.io.serializable;
public class clonetest3
{
  public static void main(string[] args) throws exception
  {
    teacher3 teacher3 = new teacher3();
    teacher3.setage(23);
    teacher3.setname("niesong");
    student3 student3 = new student3();
    student3.setage(50);
    student3.setname("wutao");
    student3.setteacher3(teacher3);
    student3 ss = (student3)student3.deepcopt();
    system.out.println(ss.getage());
    system.out.println(ss.getname());
    system.out.println("---------------------");
    system.out.println(ss.getteacher3().getage());
    system.out.println(ss.getteacher3().getname());
    system.out.println("-----------------------");
    ss.getteacher3().setage(7777);
    ss.getteacher3().setname("hhhhh");
    system.out.println(teacher3.getage());
    system.out.println(teacher3.getname());
    //虽然上面的已经改了,但是改的是那个复制对象后的那个里面的,然后那个原来的那个里面的并没有改,下面验证:::
    system.out.println("-----------------");
    system.out.println(ss.getteacher3().getage());
    system.out.println(ss.getteacher3().getname());
  }
}
class teacher3 implements serializable
{
// 上面的那个警告可以直接消除,除了使用在设置中不显示这个警告,还可以使用下面的这两条语句中的任何一条语句
//  这个serialversionuid为了让该类别serializable向后兼容
//  private static final long serialversionuid = 1l;
//  private static final long serialversionuid = 8940196742313994740l;
  private int age;
  private string name;
  public int getage()
  {
    return age;
  }
  public void setage(int age)
  {
    this.age = age;
  }
  public string getname()
  {
    return name;
  }
  public void setname(string name)
  {
    this.name = name;
  }
}
class student3 implements serializable
{
  private static final long serialversionuid = 1l;
  private int age;
  private string name;
  private teacher3 teacher3;
  public int getage()
  {
    return age;
  }
  public void setage(int age)
  {
    this.age = age;
  }
  public string getname()
  {
    return name;
  }
  public void setname(string name)
  {
    this.name = name;
  }
  public teacher3 getteacher3()
  {
    return teacher3;
  }
  public void setteacher3(teacher3 teacher3)
  {
    this.teacher3 = teacher3;
  }
  //使得序列化student3的时候也会将teacher序列化
  public object deepcopt()throws exception
  {
    bytearrayoutputstream bos = new bytearrayoutputstream();
    objectoutputstream oos = new objectoutputstream(bos);
    oos.writeobject(this);
    //将当前这个对象写到一个输出流当中,,因为这个对象的类实现了serializable这个接口,所以在这个类中
    //有一个引用,这个引用如果实现了序列化,那么这个也会写到这个输出流当中
    bytearrayinputstream bis = new bytearrayinputstream(bos.tobytearray());
    objectinputstream ois = new objectinputstream(bis);
    return ois.readobject();
    //这个就是将流中的东西读出类,读到一个对象流当中,这样就可以返回这两个对象的东西,实现深克隆
  }
}

运行结果:

Java实现克隆的三种方式实例总结

希望本文所述对大家java程序设计有所帮助。

原文链接:https://blog.csdn.net/qq_28081081/article/details/80455150

延伸 · 阅读

精彩推荐