对象的copy你兴许只是懵懂,或者是并没在意,来了解下吧。

对于的github基础代码https://github.com/chywx/JavaSE

最近学习c++,跟java很是相像,在慕课网学习c++也算是重温习了下java基础

明白了当初讲师一直强调java传递的话只有值传递,不存在引用传递,为什么一直要重复这,既然只有值传递,为啥还强调不是引用传递

毛病啊这是

学了c++才知道,原来c++有值传递,引用传递的说法,但是java只是值传递

最简单的理解就是对于方法调用

比如 f(int a,int b) 这是值传递,传递过来的值不会被修改。

再如 f(int &a,int &b)这是引用传递,传递过来的值会被修改

步入正轨,说一说java的浅拷贝(Shallow Copy)、深拷贝(Deep Copy)。

浅拷贝(Shallow Copy):①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。

通过示例来了解下,

一:

  使用构造函数实现copy

  1. public class Person {
  2. public static void main(String[] args) {
  3. Son s = new Son(10);
  4. Person p1 = new Person("大海", s);
  5. Person p2 = new Person(p1);
  6. p1.setSonName("小海");
  7. p1.getSon().setAge(12);
  8. System.out.println("p1:" + p1);// p1:Person [sonName=小海, son=Son [age=10]]
  9. System.out.println("p2:" + p2);// p2:Person [sonName=大海, son=Son [age=10]]
  10.  
  11. }
  12.  
  13. private String sonName;
  14. private Son son;
  15.  
  16. // 自定义拷贝函数
  17. public Person(Person person) {
  18. this.sonName = person.sonName;
  19. this.son = person.son;
  20. }
  21.  
  22. public Person(String sonName, Son son) {
  23. super();
  24. this.sonName = sonName;
  25. this.son = son;
  26. }
  27.  
  28. public String getSonName() {
  29. return sonName;
  30. }
  31.  
  32. public void setSonName(String sonName) {
  33. this.sonName = sonName;
  34. }
  35.  
  36. public Son getSon() {
  37. return son;
  38. }
  39.  
  40. public void setSon(Son son) {
  41. this.son = son;
  42. }
  43.  
  44. @Override
  45. public String toString() {
  46. return "Person [sonName=" + sonName + ", son=" + son + "]";
  47. }
  48.  
  49. }
  50.  
  51. class Son {
  52. private int age;
  53.  
  54. public int getAge() {
  55. return age;
  56. }
  57.  
  58. public void setAge(int age) {
  59. this.age = age;
  60. }
  61.  
  62. public Son(int age) {
  63. super();
  64. this.age = age;
  65. }
  66.  
  67. @Override
  68. public String toString() {
  69. return "Son [age=" + age + "]";
  70. }
  71.  
  72. }

结果

p1:Person [sonName=小海, son=Son [age=12]]
p2:Person [sonName=大海, son=Son [age=12]]

对于上面的实例,该person对象有两个成员,一个基本类型,一个引用类型,结果是拷贝出来的对象,基本类型的那个成员真正的实现了copy。

二:

  使用自带的clone方法,需要实现cloneable接口,不然会

Exception in thread "main" java.lang.CloneNotSupportedException:

  1. public class Person2 implements Cloneable {
  2. public static void main(String[] args) throws CloneNotSupportedException {
  3. Son2 son1 = new Son2(10);
  4.  
  5. Person2 person1 = new Person2("大海", son1);
  6. Person2 person2 = (Person2) person1.clone();
  7. person2.setSon2Name("小海");
  8. person2.getSon2().setAge(12);
  9. System.out.println(person1);
  10. System.out.println(person2);
  11. }
  12.  
  13. public Person2(String son2Name, Son2 son2) {
  14. super();
  15. this.son2Name = son2Name;
  16. this.son2 = son2;
  17. }
  18.  
  19. private String son2Name;
  20. private Son2 son2;
  21.  
  22. public String getSon2Name() {
  23. return son2Name;
  24. }
  25.  
  26. public void setSon2Name(String son2Name) {
  27. this.son2Name = son2Name;
  28. }
  29.  
  30. public Son2 getSon2() {
  31. return son2;
  32. }
  33.  
  34. public void setSon2(Son2 son2) {
  35. this.son2 = son2;
  36. }
  37.  
  38. @Override
  39. protected Object clone() throws CloneNotSupportedException {
  40. return super.clone();
  41. }
  42.  
  43. @Override
  44. public String toString() {
  45. return "Person2 [son2Name=" + son2Name + ", son2=" + son2 + "]";
  46. }
  47.  
  48. }
  49.  
  50. class Son2 {
  51. private int age;
  52.  
  53. public int getAge() {
  54. return age;
  55. }
  56.  
  57. public void setAge(int age) {
  58. this.age = age;
  59. }
  60.  
  61. @Override
  62. public String toString() {
  63. return "Son2 [age=" + age + "]";
  64. }
  65.  
  66. public Son2(int age) {
  67. super();
  68. this.age = age;
  69. }
  70.  
  71. }

结果:

Person2 [son2Name=大海, son2=Son2 [age=12]]
Person2 [son2Name=小海, son2=Son2 [age=12]]

使用自带的copy实现浅拷贝

---------------------------------------------------------------------------------------------------

深拷贝

  相对于浅拷贝而言,对于引用类型的修改,并不会影响到对应的copy对象的值。每一层的每个对象都进行浅拷贝=深拷贝。

一:

  还是使用clone方法,只不过得手动重写一下。

上代码

  1. public class Person3 implements Cloneable {
  2. public static void main(String[] args) throws CloneNotSupportedException {
  3. Son3 son1 = new Son3(10);
  4. Person3 person1 = new Person3("大海", son1);
  5. Person3 person2 = (Person3) person1.clone();
  6. person2.setSon2Name("小海");
  7. person2.getSon3().setAge(12);//修改对应的引用对象的值。
  8. System.out.println(person1);
  9. System.out.println(person2);
  10. }
  11.  
  12. public Person3(String son2Name, Son3 son3) {
  13. super();
  14. this.son2Name = son2Name;
  15. this.son3 = son3;
  16. }
  17.  
  18. private String son2Name;
  19. private Son3 son3;
  20.  
  21. public String getSon2Name() {
  22. return son2Name;
  23. }
  24.  
  25. public void setSon2Name(String son2Name) {
  26. this.son2Name = son2Name;
  27. }
  28.  
  29. public Son3 getSon3() {
  30. return son3;
  31. }
  32.  
  33. public void setSon3(Son3 son3) {
  34. this.son3 = son3;
  35. }
  36.  
  37. @Override
  38. protected Object clone() throws CloneNotSupportedException {
  39. Person3 clone = (Person3) super.clone();
  40. clone.setSon3((Son3) clone.getSon3().clone());
  41. return clone;
  42. }
  43.  
  44. @Override
  45. public String toString() {
  46. return "Person3 [son2Name=" + son2Name + ", son3=" + son3 + "]";
  47. }
  48.  
  49. }
  50.  
  51. class Son3 implements Cloneable {
  52. private int age;
  53.  
  54. public int getAge() {
  55. return age;
  56. }
  57.  
  58. public void setAge(int age) {
  59. this.age = age;
  60. }
  61.  
  62. @Override
  63. public String toString() {
  64. return "Son2 [age=" + age + "]";
  65. }
  66.  
  67. public Son3(int age) {
  68. super();
  69. this.age = age;
  70. }
  71.  
  72. @Override
  73. protected Object clone() throws CloneNotSupportedException {
  74. return super.clone();
  75. }
  76.  
  77. }

结果:

Person3 [son2Name=大海, son3=Son2 [age=10]]

Person3 [son2Name=小海, son3=Son2 [age=12]]

方法二:

  显然对于多个对象的话,显然就很吃力。可以使用另一种方式,

  将对象序列化为字节序列后,默认会将该对象的整个对象图进行序列化,再通过反序列即可完美地实现深拷贝。

  1. public class Person4 implements Serializable {
  2. public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
  3. Son4 son = new Son4(10);
  4. Person4 person1 = new Person4("大海", son);
  5. //通过序列化方法实现深拷贝
  6. ByteArrayOutputStream bos=new ByteArrayOutputStream();
  7. ObjectOutputStream oos=new ObjectOutputStream(bos);
  8. oos.writeObject(person1);
  9. oos.flush();
  10. ObjectInputStream ois=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
  11. Person4 person2=(Person4)ois.readObject();
  12. person1.setSon4Name("小海");
  13. person1.getSon4().setAge(12);
  14. System.out.println(person1.toString());
  15. System.out.println(person2.toString());
  16. }
  17.  
  18. public Person4(String son4Name, Son4 son4) {
  19. super();
  20. this.son4Name = son4Name;
  21. this.son4 = son4;
  22. }
  23.  
  24. private String son4Name;
  25. private Son4 son4;
  26.  
  27. public String getSon4Name() {
  28. return son4Name;
  29. }
  30.  
  31. public void setSon4Name(String son4Name) {
  32. this.son4Name = son4Name;
  33. }
  34.  
  35. public Son4 getSon4() {
  36. return son4;
  37. }
  38.  
  39. public void setSon4(Son4 son4) {
  40. this.son4 = son4;
  41. }
  42.  
  43. @Override
  44. public String toString() {
  45. return "Person4 [son4Name=" + son4Name + ", son4=" + son4 + "]";
  46. }
  47. }
  48.  
  49. class Son4 implements Serializable {
  50. private int age;
  51.  
  52. public int getAge() {
  53. return age;
  54. }
  55.  
  56. public void setAge(int age) {
  57. this.age = age;
  58. }
  59. @Override
  60. public String toString() {
  61. return "Son2 [age=" + age + "]";
  62. }
  63.  
  64. public Son4(int age) {
  65. super();
  66. this.age = age;
  67. }
  68.  
  69. }

这是实现序列化接口方案,nice.

perfect!!!到位

记录下听得歌曲。

  1. 绝世
  2. (张克帆)
  3. 世间种种的诱惑
  4. 不惊不扰我清梦
  5. 山高路远不绝我
  6. 追踪你绝美的笑容
  7. 登高一呼时才懂
  8. 始终在为你心痛
  9. 俯首对花影摇动
  10. 都是东风在捉弄
  11. 世间种种的迷惑
  12. 都是因你而猜错
  13. 水光月光又交融
  14. 描述这朗朗的夜空
  15. 生死到头的相从
  16. 似狂花落叶般从容
  17. 当一切泯灭如梦
  18. 就在远山被绝世尘封

java浅拷贝和深拷贝(基础也是很重要的)的更多相关文章

  1. Java 浅拷贝、深拷贝,你知多少?

    这是今天我们在技术群里面讨论的一个知识点,讨论的相当激烈,由于对这一块使用的比较少,所以对这一块多少有些盲区.这篇文章总结了所讨论的内容,希望这篇文章对你有所帮助. 在 Java 开发中,对象拷贝或者 ...

  2. Java 浅拷贝和深拷贝的理解和实现方式

    Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...

  3. java 浅拷贝和深拷贝 对象克隆clone

    分一下几点讨论: 为什么要克隆? 如何实现克隆 浅克隆和深克隆 解决多层克隆问题 总结 一:为什么要克隆? 大家先思考一个问题,为什么需要克隆对象?直接new一个对象不行吗? 答案是:克隆的对象可能包 ...

  4. 【转】Java 浅拷贝和深拷贝的理解和实现方式

    Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...

  5. 浅谈java浅拷贝和深拷贝

    前言:深拷贝和浅拷贝的区别是什么? 浅拷贝:被复制的对象的所有变量都含有原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之, 浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象.深拷 ...

  6. Java 浅拷贝和深拷贝

    一看就懂的,java深拷贝浅拷贝 将一个对象的引用复制给另外一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅拷贝,第三种是深拷贝.所以大家知道了哈,这三种概念实际上都是为了拷贝对象啊. ...

  7. Java 浅拷贝,深拷贝

         从Java 强引用.软引用,弱引用http://blog.csdn.net/jltxgcy/article/details/35558465一文中,我们看到把一个对象赋值给另一个对象,本质上 ...

  8. Java浅拷贝与深拷贝(思维导图)

    图1 拷贝思维导图(点击查看图片) 1,拷贝 有两个相同属性的对象A和B,A拥有初始化值,将其值拷贝到B中,使得B拥有与A“相同”数据的属性!注意这里的相同我有加双引号! 相同可能表示这么几个意思:① ...

  9. java浅拷贝和深拷贝

    转:http://blog.csdn.net/u014727260/article/details/55003402 实现clone的2点: 1,clone方法是Object类的一个方法,所以任何一个 ...

随机推荐

  1. Linux type命令的用法

    一般情况下,type命令被用于判断另外一个命令是否是内置命令,但是它实际上有更多的用法. 1.判断一个名字当前是否是alias.keyword.function.builtin.file或者什么都不是 ...

  2. 数组C - 玛雅日历

    During his last sabbatical, professor M. A. Ya made a surprising discovery about the old Maya calend ...

  3. 阿里云 配置FTP 无法连接问题,2017年7月后

    被阿里云坑飞,2017年7月上线的安全组,我压根不知道 新服务器 配置防火墙后怎么也不起作用,也暂时关不了防火墙 iptables stop #无效 搞了半天 才知道TM  不需要在linx服务器上自 ...

  4. 【转】CentOS7 yum方式配置LAMP环境

    采用Yum方式搭建: Apache+Mysql+PHP环境 原文地址: http://www.cnblogs.com/zutbaz/p/4420791.html 1.安装Apache yum inst ...

  5. NYOJ 1022 合纵连横 (并查集)

    题目链接 描述 乱世天下,诸侯割据.每个诸侯王都有一片自己的领土.但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大.而实力弱的诸侯王为了不让自己的领 ...

  6. 图片轮播器——jquery插件

    下载:http://files.cnblogs.com/files/wordblog/jiaoben828.rar

  7. app 测试基础

    1. 安装和启动 (1) OTA安装测试 ·         app必须能够通过ota安装到测试设备上 ·         如果app安装完后没有icon,那么必须能够通过其他的方法来启动这个app ...

  8. angular导出文件保存在本地

    $scope.ev_click = function(obj){ var ev = document.createEvent("MouseEvents"); ev.initMous ...

  9. ASLR pe 分析

    ASLR 转:http://www.cnblogs.com/dliv3/p/6411814.html 3ks @author:dlive 微软从windows vista/windows server ...

  10. 【swupdate文档 三】SWUpdate: 嵌入式系统的软件升级

    SWUpdate: 嵌入式系统的软件升级 概述 本项目被认为有助于从存储媒体或网络更新嵌入式系统.但是,它应该主要作为一个框架来考虑,在这个框架中可以方便地向应用程序添加更多的协议或安装程序(在SWU ...