从Java 强引用。软引用,弱引用http://blog.csdn.net/jltxgcy/article/details/35558465一文中,我们看到把一个对象赋值给另一个对象,本质上是添加了引用计数。可是它们都指向相同的堆内存。它们是一个对象。假设我们想要一个独立的对象。改怎么办呢?答案是clone。

 

1、浅拷贝

     浅拷贝是指拷贝对象时只拷贝对象本身(包括对象中的基本变量),而不拷贝对象包括的引用指向的对象。

      ShallowCopy.java

class Professor0 implements Cloneable {
String name;
int age; Professor0(String name, int age) {
this.name = name;
this.age = age;
} public Object clone() throws CloneNotSupportedException {
return super.clone();
}
} class Student0 implements Cloneable {
String name;// 常量对象。
int age;
Professor0 p;// 学生1和学生2的引用值都是一样的。 Student0(String name, int age, Professor0 p) {
this.name = name;
this.age = age;
this.p = p;
} public Object clone() {
Student0 o = null;
try {
o = (Student0) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
} return o;
}
} public class ShallowCopy {
public static void main(String[] args) {
Professor0 p = new Professor0("wangwu", 50);
Student0 s1 = new Student0("zhangsan", 18, p);
Student0 s2 = (Student0) s1.clone();
s2.p.name = "lisi";
s2.p.age = 30;
s2.name = "z";
s2.age = 45;
System.out.println("学生s1的姓名:" + s1.name + "\n学生s1教授的姓名:" + s1.p.name + "," + "\n学生s1教授的年纪" + s1.p.age);// 学生1的教授
}
}

      结果:

     s2.p改变了s1.p的内容。而s2.name和s2.age没有改变s1.name和s1.age的内容。

2、深拷贝

     深拷贝不仅拷贝对象本身。并且拷贝对象包括的引用指向的全部对象。

class Professor implements Cloneable {
String name;
int age; Professor(String name, int age) {
this.name = name;
this.age = age;
} public Object clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
return o;
}
} class Student implements Cloneable {
String name;
int age;
Professor p; Student(String name, int age, Professor p) {
this.name = name;
this.age = age;
this.p = p;
} public Object clone() {
Student o = null;
try {
o = (Student) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
o.p = (Professor) p.clone();
return o;
}
} public class DeepCopy {
public static void main(String args[]) {
long t1 = System.currentTimeMillis();
Professor p = new Professor("wangwu", 50);
Student s1 = new Student("zhangsan", 18, p);
Student s2 = (Student) s1.clone();
s2.p.name = "lisi";
s2.p.age = 30;
System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age);// 学生1的教授不改变。
long t2 = System.currentTimeMillis();
System.out.println(t2-t1);//耗时
}
}

     结果:

     s2.p不能改变s1.p的内容。

由于是不同对象。

3、当然我们另一种深拷贝方法。就是将对象串行化:

     可是串行化却非常耗时,在一些框架中,我们便能够感受到,它们往往将对象进行串行化后进行传递。耗时较多。

     DeepCopy2.java

import java.io.*;
//Serialization is time-consuming
class Professor2 implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
String name;
int age; Professor2(String name, int age) {
this.name = name;
this.age = age;
}
} class Student2 implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
String name;// 常量对象。 int age;
Professor2 p;// 学生1和学生2的引用值都是一样的。 Student2(String name, int age, Professor2 p) {
this.name = name;
this.age = age;
this.p = p;
} public Object deepClone() throws IOException, OptionalDataException,
ClassNotFoundException {
// 将对象写到流里
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
// 从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
} } public class DeepCopy2 { /**
* @param args
*/
public static void main(String[] args) throws OptionalDataException,
IOException, ClassNotFoundException {
long t1 = System.currentTimeMillis();
Professor2 p = new Professor2("wangwu", 50);
Student2 s1 = new Student2("zhangsan", 18, p);
Student2 s2 = (Student2) s1.deepClone();
s2.p.name = "lisi";
s2.p.age = 30;
System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // 学生1的教授不改变。 long t2 = System.currentTimeMillis();
System.out.println(t2-t1);//耗时
} }

      结果:

     s2.p不能改变s1.p的内容。

由于是不同对象。

     从图中也能看出将对象进行串行化后进行传递,耗时较多。

Java 浅拷贝,深拷贝的更多相关文章

  1. Java 浅拷贝 深拷贝

    两者区别主要在于引用数据类型的属性,对于基本数据类型采用的是值传递,所以两者一样: 对于浅拷贝,引用数据类型只会进行引用传递,即复制一份引用值(内存地址)给新对象,一个对象的变化会影响到另一个的引用属 ...

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

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

  3. Java的深拷贝和浅拷贝

    关于Java的深拷贝和浅拷贝,简单来说就是创建一个和已知对象一模一样的对象.可能日常编码过程中用的不多,但是这是一个面试经常会问的问题,而且了解深拷贝和浅拷贝的原理,对于Java中的所谓值传递或者引用 ...

  4. java浅拷贝和深拷贝(基础也是很重要的)

    对象的copy你兴许只是懵懂,或者是并没在意,来了解下吧. 对于的github基础代码https://github.com/chywx/JavaSE 最近学习c++,跟java很是相像,在慕课网学习c ...

  5. Java基础 深拷贝浅拷贝

    Java基础 深拷贝浅拷贝 非基本数据类型 需要new新空间 class Student implements Cloneable{ private int id; private String na ...

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

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

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

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

  8. JS中有关对象的继承以及实例化、浅拷贝深拷贝的奥秘

    一.属性的归属问题 JS对象中定义的属性和方法如果不是挂在原型链上的方法和属性(直接通过如类似x的方式进行定义)都只是在该对象上,对原型链上的没有影响.对于所有实例共用的方法可直接定义在原型链上这样实 ...

  9. $.extend()浅拷贝深拷贝

    参考网址:http://bijian1013.iteye.com/blog/2255037 jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象. 注意:1. 如果只为$.ex ...

  10. Python__学习路上的坑之--引用,浅拷贝,深拷贝

    copy : 相当于只是拷贝表面一层,如果里面还有深层次的引用,那么也是直接拷贝引用的地址,而且如果拷贝对象是不可变类型比如元组,那么也是直接拷贝引用. deepcopy: 无论是拷贝可变类型还是不可 ...

随机推荐

  1. Linux卸载搭建环境

    本章内容 卸载Apache PHP MySQL 卸载Apache 查看apache安装版本 $ apachectl -v 查看安装httpd相关软件包(红色部分) sudo yum list inst ...

  2. rsync算法原理和工作流程分析

    本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释.本文不会介绍如何使用rsync命令(见rsync基本用法),而是详细解释它如何实现高效的增 ...

  3. MySQL中的事务及读写锁实现并发访问控制

    一.并发控制中锁的概念 锁是并发控制中最核心的概念之一,在MySQL中的锁分两大类,一种是读锁,一种是写锁,读锁也可以称为共享锁(shared lock),写锁也通常称为排它锁(exclusive l ...

  4. ssh介绍

      一.SSH概念(百度) SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SSH 为建立在应用层基础上的安全协议.SSH ...

  5. ubuntu16.04LTS更换阿里源

    ubuntu16.04LTS更换阿里源 sudo gedit /etc/apt/sources.list 替换:    # deb cdrom:[Ubuntu 16.04 LTS _Xenial Xe ...

  6. html特殊字体显示

    1.下载需要显示的ttf字体. 2.css样式调用. /* 微软雅黑 */ @font-face { font-family: microsoftyahei; src: url('${pageCont ...

  7. Java框架之Struts2(四)

    一.ComboGrid 扩展自$.fn.combo.defaults和$.fn.datagrid.defaults.使用$.fn.combogrid.defaults重写默认值对象.数据表格下拉框结合 ...

  8. code for qint function

    function [p,y,a] = qint(ym1,y0,yp1) %QINT - quadratic interpolation of three adjacent samples % % [p ...

  9. lfs(systemv版本)学习笔记-第4页

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! lfs(systemv版本)学习笔记第3页:https://www.cnblogs.com/renren-study-notes ...

  10. html一些标签在不同浏览器或者不同版本浏览器的注意事项

    最近在IE10下运行一个以前的做web系统发现了两个小问题:   一.图片上使用"alt"属性来添加一些文字提示信息在IE10下无法正常显示出来   上网查了一下原因:原来是现在一 ...