1.java里的clone分为: 
A:浅复制(浅克隆): 浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 
b:深复制(深克隆):深复制把要复制的对象所引用的对象都复制了一遍。 
Java中对象的克隆,为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。必须要遵循下面三点 
1.在派生类中覆盖基类的clone()方法,并声明为public【Object类中的clone()方法为protected的】。 
2.在派生类的clone()方法中,调用super.clone()。 
3.在派生类中实现Cloneable接口。

Object类里的clone方法是浅复制(浅克隆)

浅复制(浅克隆)的例子如下:

  1. public class CloneTest
  2. {
  3. public static void main(String[] args) throws Exception
  4. {
  5. // teacher对象将被clone出来的Student对象共享.
  6. Teacher teacher = new Teacher();
  7. teacher.setAge(40);
  8. teacher.setName("Teacher zhang");
  9. Student student1 = new Student();
  10. student1.setAge(20);
  11. student1.setName("zhangsan");
  12. student1.setTeacher(teacher);
  13. // 复制出来一个对象student2
  14. Student student2 = (Student) student1.clone();
  15. System.out.println(student2.getAge());
  16. System.out.println(student2.getName());
  17. System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
  18. System.out.println(student1.getTeacher().getAge());
  19. System.out.println(student1.getTeacher().getName());
  20. // 修改student2的引用对象
  21. student2.getTeacher().setAge(50);
  22. student2.getTeacher().setName("Teacher Li");
  23. System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
  24. System.out.println(student1.getTeacher().getAge());
  25. System.out.println(student1.getTeacher().getName());
  26. }
  27. }
  28. class Teacher
  29. {
  30. public int age;
  31. public String name;
  32. public int getAge()
  33. {
  34. return age;
  35. }
  36. public void setAge(int age)
  37. {
  38. this.age = age;
  39. }
  40. public String getName()
  41. {
  42. return name;
  43. }
  44. public void setName(String name)
  45. {
  46. this.name = name;
  47. }
  48. }
  49. class Student implements Cloneable
  50. {
  51. public int age;
  52. public String name;
  53. public Teacher teacher;
  54. public int getAge()
  55. {
  56. return age;
  57. }
  58. public void setAge(int age)
  59. {
  60. this.age = age;
  61. }
  62. public String getName()
  63. {
  64. return name;
  65. }
  66. public void setName(String name)
  67. {
  68. this.name = name;
  69. }
  70. public Teacher getTeacher()
  71. {
  72. return teacher;
  73. }
  74. public void setTeacher(Teacher teacher)
  75. {
  76. this.teacher = teacher;
  77. }
  78. @Override
  79. public Object clone() throws CloneNotSupportedException
  80. {
  81. return super.clone();
  82. }
  83. }
  84. 输出结果为:
  85. 20
  86. zhangsan
  87. ~~~~~~~~~~~~~~~~~~~~~~
  88. 40
  89. Teacher zhang
  90. ~~~~~~~~~~~~~~~~~~~~~~
  91. 50
  92. Teacher Li

2.深复制(深Clone)例子:

  1. public class DeepCloneTest
  2. {
  3. public static void main(String[] args) throws Exception
  4. {
  5. // teacher对象将不被clone出来的Student对象共享.
  6. Teacher teacher = new Teacher();
  7. teacher.setAge(40);
  8. teacher.setName("Teacher zhang");
  9. Student student1 = new Student();
  10. student1.setAge(20);
  11. student1.setName("zhangsan");
  12. student1.setTeacher(teacher);
  13. // 复制出来一个对象student2
  14. Student student2 = (Student) student1.clone();
  15. System.out.println(student2.getAge());
  16. System.out.println(student2.getName());
  17. System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
  18. System.out.println(student1.getTeacher().getAge());
  19. System.out.println(student1.getTeacher().getName());
  20. // 修改student2的引用对象
  21. student2.getTeacher().setAge(50);
  22. student2.getTeacher().setName("Teacher Li");
  23. System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
  24. System.out.println(student1.getTeacher().getAge());
  25. System.out.println(student1.getTeacher().getName());
  26. }
  27. }
  28. class Teacher implements Cloneable
  29. {
  30. public int age;
  31. public String name;
  32. public int getAge()
  33. {
  34. return age;
  35. }
  36. public void setAge(int age)
  37. {
  38. this.age = age;
  39. }
  40. public String getName()
  41. {
  42. return name;
  43. }
  44. public void setName(String name)
  45. {
  46. this.name = name;
  47. }
  48. @Override
  49. public Object clone() throws CloneNotSupportedException
  50. {
  51. return super.clone();
  52. }
  53. }
  54. class Student implements Cloneable
  55. {
  56. public int age;
  57. public String name;
  58. public Teacher teacher;
  59. public int getAge()
  60. {
  61. return age;
  62. }
  63. public void setAge(int age)
  64. {
  65. this.age = age;
  66. }
  67. public String getName()
  68. {
  69. return name;
  70. }
  71. public void setName(String name)
  72. {
  73. this.name = name;
  74. }
  75. public Teacher getTeacher()
  76. {
  77. return teacher;
  78. }
  79. public void setTeacher(Teacher teacher)
  80. {
  81. this.teacher = teacher;
  82. }
  83. @Override
  84. public Object clone() throws CloneNotSupportedException
  85. {
  86. Student student = (Student) super.clone();
  87. // 将引用的对象teacher也clone下
  88. student.setTeacher((Teacher) (student.getTeacher().clone()));
  89. return student;
  90. }
  91. }
  92. 输出结果为:
  93. 20
  94. zhangsan
  95. ~~~~~~~~~~~~~~~~~~~~~~
  96. 40
  97. Teacher zhang
  98. ~~~~~~~~~~~~~~~~~~~~~~
  99. 40
  100. Teacher zhang

3.利用序列化来做深复制,把对象写到流里的过程是序列化(Serilization)过程,而把对象从流中读出来的过程则叫做反序列化(Deserialization)过程。应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。,利用这个特性,可以做深拷贝

    1. import java.io.ByteArrayInputStream;
    2. import java.io.ByteArrayOutputStream;
    3. import java.io.ObjectInputStream;
    4. import java.io.ObjectOutputStream;
    5. import java.io.Serializable;
    6. //利用序列化来做深复制
    7. //深clone
    8. public class DeepCloneTest
    9. {
    10. public static void main(String[] args) throws Exception
    11. {
    12. // teacher对象将不被clone出来的Student对象共享.
    13. Teacher teacher = new Teacher();
    14. teacher.setAge(40);
    15. teacher.setName("Teacher zhang");
    16. Student student1 = new Student();
    17. student1.setAge(20);
    18. student1.setName("zhangsan");
    19. student1.setTeacher(teacher);
    20. // 复制出来一个对象student2
    21. Student student2 = (Student) student1.deepCopy();
    22. System.out.println(student2.getAge());
    23. System.out.println(student2.getName());
    24. System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
    25. System.out.println(student1.getTeacher().getAge());
    26. System.out.println(student1.getTeacher().getName());
    27. // 修改student2的引用对象
    28. student2.getTeacher().setAge(50);
    29. student2.getTeacher().setName("Teacher Li");
    30. System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
    31. System.out.println(student1.getTeacher().getAge());
    32. System.out.println(student1.getTeacher().getName());
    33. }
    34. }
    35. class Teacher implements Serializable
    36. {
    37. private static final long serialVersionUID = -8834559347461591191L;
    38. public int age;
    39. public String name;
    40. public int getAge()
    41. {
    42. return age;
    43. }
    44. public void setAge(int age)
    45. {
    46. this.age = age;
    47. }
    48. public String getName()
    49. {
    50. return name;
    51. }
    52. public void setName(String name)
    53. {
    54. this.name = name;
    55. }
    56. }
    57. class Student implements Serializable
    58. {
    59. // serialVersionUID
    60. // 如果你的对象序列化后存到硬盘上面后,可是后来你却更改了类的field(增加或减少或改名),当你反序列化时,就会出现Exception的,这样就会造成不兼容性的问题。
    61. // 但当serialVersionUID相同时,它就会将不一样的field以type的缺省值赋值(如int型的是0,String型的是null等),这个可以避开不兼容性的问题。所以最好给serialVersionUID赋值
    62. private static final long serialVersionUID = 7991552226614088458L;
    63. public int age;
    64. public String name;
    65. public Teacher teacher;
    66. public int getAge()
    67. {
    68. return age;
    69. }
    70. public void setAge(int age)
    71. {
    72. this.age = age;
    73. }
    74. public String getName()
    75. {
    76. return name;
    77. }
    78. public void setName(String name)
    79. {
    80. this.name = name;
    81. }
    82. public Teacher getTeacher()
    83. {
    84. return teacher;
    85. }
    86. public void setTeacher(Teacher teacher)
    87. {
    88. this.teacher = teacher;
    89. }
    90. public Object deepCopy() throws Exception
    91. {
    92. // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
    93. ByteArrayOutputStream bos = new ByteArrayOutputStream();
    94. ObjectOutputStream oos = new ObjectOutputStream(bos);
    95. oos.writeObject(this);
    96. // 将流序列化成对象
    97. ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    98. ObjectInputStream ois = new ObjectInputStream(bis);
    99. return ois.readObject();
    100. }
    101. }
    102. 输出结果为:
    103. 20
    104. zhangsan
    105. ~~~~~~~~~~~~~~~~~~~~~~
    106. 40
    107. Teacher zhang
    108. ~~~~~~~~~~~~~~~~~~~~~~
    109. 40
    110. Teacher zhang

JAVA 对象拷贝的更多相关文章

  1. Java对象拷贝备忘

    列举 //cglib net.sf.cglib.beans.BeanCopier.create net.sf.cglib.beans.BeanCopier.copy //spring-beans or ...

  2. java对象拷贝和复制

    参考文章:http://blog.csdn.net/XIAXIA__/article/details/41652057 解决问题:深拷贝.浅拷贝 和普通的对象赋值有什么区别? 对象复制 例如:Pers ...

  3. Java 对象拷贝方式

    (1)BeanUtils.cloneBean()使用: http://www.cnblogs.com/fervour/archive/2009/12/18/1627868.html package c ...

  4. Java Object 对象拷贝

    Java Object 对象拷贝 @author ixenos JAVA 对象拷贝 Java里的clone分为:  1.浅拷贝:浅复制仅仅复制所考虑的对象,而不复制它所引用的对象,Object类里的c ...

  5. 通过与C++程序对比,彻底搞清楚JAVA的对象拷贝

    目录 一.背景 二.JAVA对象拷贝的实现 2.1 浅拷贝 2.2 深拷贝的实现方法一 2.3 深拷贝的实现方法二 2.3.1 C++拷贝构造函数 2.3.2 C++源码 2.3.3 JAVA通过拷贝 ...

  6. Java Object 对象拷贝答疑

    Java Object 对象拷贝答疑 @author ixenos 摘要:在对象的clone过程需要注意的几点.关于关键字this.super 关于clone[对象拷贝] 在实际编程过程,有时候我们会 ...

  7. Java 开发中的对象拷贝

    前言 在 Java 开发中,很多时候需要将两个属性基本相同的对象进行属性复制,比如 DO 转 VO等等. 本文主要介绍自己实现的简易拷贝工具类与 Spring 提供的属性拷贝的对比. Spring 提 ...

  8. java bean对象拷贝

    Java的bean的属性复制,大家可以都看一下. 谈谈Java开发中的对象拷贝http://www.wtnull.com/view/2/e6a7a8818da742758bcd8b73d49d6be2 ...

  9. Java中对象拷贝的两种方式

    引用的拷贝 //引用拷贝 private static void copyReferenceObject(){ Person p = new Person(23, "zhang") ...

随机推荐

  1. 05-图2. Saving James Bond - Easy Version (25)

    1 边界和湖心小岛分别算一个节点.连接全部距离小于D的鳄鱼.时间复杂度O(N2) 2 推断每一个连通图的节点中是否包括边界和湖心小岛,是则Yes否则No 3 冗长混乱的函数參数 #include &l ...

  2. 安装android studio 出现的路径问题 tools.jar' seems to be not in Android Studio classpath

    尝试一下android studio  ,谁知出现路径问题 'tools.jar' seems to be not in Android Studio classpath. Please ensure ...

  3. nyoj 756 重建二叉树

    重建二叉树主要是给你一颗二叉树的前序遍历的结果和中序遍历的结果或者后序遍历的结果或者中序遍历的结果,让你求出其中的后序遍历的结果或者前序遍历的结果,这里知道其中的两个就能求出第三个,但是知道的两个必须 ...

  4. GraphViz web版

    http://graphviz-dev.appspot.com/ 用来把dot语言的图画出来,很多地方用dot语言来画图,比如doxygen的类关系,gperftools的分析结果等.

  5. ASP.NET页面周期

    上图为ASP.NET页面生命周期图. 以下详细讲解一下ASP.NET的页面生命周期.   请求页 请求页发生在页生命周期之前.用户请求时,ASP.NET将确定是否需要分析和编译页面,或者是否可以在不运 ...

  6. 《CSS网站布局实录》学习笔记(二)

    第二章 XHTML与CSS基础 2.1 XHTML基础 XHTML是网页代码的核心内容,标准XHTML代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  7. PHP与memcache和memcached以及安装使用

    老规则,在作者寒冰讲之前我们要来明确memcache与memcached这两个东西到底是什么? 说法一: 两个不同版本的php的memcached的客户端 new memcache是pecl扩展库版本 ...

  8. 汇编笔记之 ret 、retf和call

    作用: ret  将 栈顶数据出栈到IP retf 将 栈顶数据出栈到IP ,然后再次将栈顶数据出栈到CS 这样一来,可以使程序跳转到已经定义好了的代码段去执行. call 语法 call s0 (如 ...

  9. 使用shiro安全框架上传文件时用HttpSession获取ServletContext为null问题解决方法。

    <!--在shiroFilter 中加入一下配置--> <init-param> <param-name>targetFilterLifecycle</par ...

  10. 【转】Qt 事件处理机制 (下篇)

    转自:http://mobile.51cto.com/symbian-272816.htm 在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent. 接下来依次谈谈Qt中有谁来产生.分 ...