Java 浅拷贝,深拷贝
从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 浅拷贝,深拷贝的更多相关文章
- Java 浅拷贝 深拷贝
两者区别主要在于引用数据类型的属性,对于基本数据类型采用的是值传递,所以两者一样: 对于浅拷贝,引用数据类型只会进行引用传递,即复制一份引用值(内存地址)给新对象,一个对象的变化会影响到另一个的引用属 ...
- Java 浅拷贝和深拷贝的理解和实现方式
Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...
- Java的深拷贝和浅拷贝
关于Java的深拷贝和浅拷贝,简单来说就是创建一个和已知对象一模一样的对象.可能日常编码过程中用的不多,但是这是一个面试经常会问的问题,而且了解深拷贝和浅拷贝的原理,对于Java中的所谓值传递或者引用 ...
- java浅拷贝和深拷贝(基础也是很重要的)
对象的copy你兴许只是懵懂,或者是并没在意,来了解下吧. 对于的github基础代码https://github.com/chywx/JavaSE 最近学习c++,跟java很是相像,在慕课网学习c ...
- Java基础 深拷贝浅拷贝
Java基础 深拷贝浅拷贝 非基本数据类型 需要new新空间 class Student implements Cloneable{ private int id; private String na ...
- Java 浅拷贝、深拷贝,你知多少?
这是今天我们在技术群里面讨论的一个知识点,讨论的相当激烈,由于对这一块使用的比较少,所以对这一块多少有些盲区.这篇文章总结了所讨论的内容,希望这篇文章对你有所帮助. 在 Java 开发中,对象拷贝或者 ...
- 【转】Java 浅拷贝和深拷贝的理解和实现方式
Java中的对象拷贝(Object Copy)指的是将一个对象的所有属性(成员变量)拷贝到另一个有着相同类类型的对象中去.举例说明:比如,对象A和对象B都属于类S,具有属性a和b.那么对对象A进行拷贝 ...
- JS中有关对象的继承以及实例化、浅拷贝深拷贝的奥秘
一.属性的归属问题 JS对象中定义的属性和方法如果不是挂在原型链上的方法和属性(直接通过如类似x的方式进行定义)都只是在该对象上,对原型链上的没有影响.对于所有实例共用的方法可直接定义在原型链上这样实 ...
- $.extend()浅拷贝深拷贝
参考网址:http://bijian1013.iteye.com/blog/2255037 jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象. 注意:1. 如果只为$.ex ...
- Python__学习路上的坑之--引用,浅拷贝,深拷贝
copy : 相当于只是拷贝表面一层,如果里面还有深层次的引用,那么也是直接拷贝引用的地址,而且如果拷贝对象是不可变类型比如元组,那么也是直接拷贝引用. deepcopy: 无论是拷贝可变类型还是不可 ...
随机推荐
- fastdfs集群版搭建(一)- storage集群搭建与统一入口访问
前言 接着上篇博客:详细的最新版fastdfs单机版搭建,今天来讲讲fastdfs的集群搭建,限于篇幅,今天先搭建stoarge集群,并实现统一的http访问方式: 没看我上篇博客的小伙伴,最好先去瞅 ...
- 微信小程序https配置
先简单说下什么是https,https与http区别 ,以及https的原理 什么是https 在说HTTPS之前先说说什么是HTTP,HTTP就是我们平时浏览网页时候使用的一种协议.HTTP协议传输 ...
- SPI 驱动框架
SPI 驱动框架 1. 枚举过程 drivers/spi/spi.c: spi_register_board_info /* 对于每一个spi_master,调用spi_match_master_to ...
- SQL 数据库加字段声明
ALTER TABLE dbo.C_TrainPlan ADD MailCost DATETIME EXECUTE sp_addextendedproperty N'MS_Description', ...
- Mysql存储过程入门介绍
delimiter //一般情况下MYSQL以:结尾表示确认输入并执行语句,但在存储过程中:不是表示结束,因此可以用该命令将:号改为//表示确认输入并执行. 一.创建存储过程 1.基本语法: crea ...
- elasticsearch6.7 05. Document APIs(4)Delete API
3.Delete API delete API 可以让你删除一个特定id的文档,下面例子删除twitter索引中_doc类型.id为1的文档: DELETE /twitter/_doc/1 返回结果: ...
- 微信服务号获取openid方法
public function tetst(){ if(!isset($_GET['code'])){ $APPID = $this->app_id; $ran = rand(1,100); / ...
- Python 中 and 和 or 的短路原则
对于 and 来说: 如果第一个条件的结论为假,那么 and 前后两个条件组成的表达式计算结果一定为假,后面的条件计算机不会进行计算 对于 or 来说: 如果第一个条件的结论为真,那么 or 前后两个 ...
- 【读书笔记】iOS-Settings Bundle
一,打开工程--->右键--->Add File--->iOS-->Resource-->Settings Bundle. 二,会弹出如下对话框---->Creat ...
- IDEA项目搭建六——使用Eureka和Ribbon进行项目服务化
一.Eureka的作用 这里先简单说明使用eureka进行业务层隔离,实现项目服务化也可以理解为微服务,我一直崇尚先实现代码再学习理论,先简单上手进行操作,eureka使用分为三块,1是服务注册中心, ...