Java基础——克隆
1、克隆
假设有一个对象object1,在某处又需要一个跟object1一样的实例object2,这两个对象是绝对独立的,不会因为某一个修改另一个随之改变,这样,我们不能直接将对象objec1t的引用赋予object2,object2=object, 这样两个引用仍然指向的是同一个对象,不是两个对象,所以就需要将object1的属性克隆到object2身上
Java中克隆分为两种,浅克隆和深克隆
2、浅克隆
把原型对象中成员变量为值类型的属性都复制给克隆对象,把原型对象中成员变量为引用类型的引用地址也复制给克隆对象
会复制原型对象,但不会复制它所引用的对象
浅克隆只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化
Object类中的clone()方法就是浅克隆
/**
* Creates and returns a copy of this object. The precise meaning
* of "copy" may depend on the class of the object. The general
* intent is that, for any object {@code x}, the expression:
* <blockquote>
* <pre>
* x.clone() != x</pre></blockquote>
* will be true, and that the expression:
* <blockquote>
* <pre>
* x.clone().getClass() == x.getClass()</pre></blockquote>
* will be {@code true}, but these are not absolute requirements.
* While it is typically the case that:
* <blockquote>
* <pre>
* x.clone().equals(x)</pre></blockquote>
* will be {@code true}, this is not an absolute requirement.
* <p>
* By convention, the returned object should be obtained by calling
* {@code super.clone}. If a class and all of its superclasses (except
* {@code Object}) obey this convention, it will be the case that
* {@code x.clone().getClass() == x.getClass()}.
* <p>
* By convention, the object returned by this method should be independent
* of this object (which is being cloned). To achieve this independence,
* it may be necessary to modify one or more fields of the object returned
* by {@code super.clone} before returning it. Typically, this means
* copying any mutable objects that comprise the internal "deep structure"
* of the object being cloned and replacing the references to these
* objects with references to the copies. If a class contains only
* primitive fields or references to immutable objects, then it is usually
* the case that no fields in the object returned by {@code super.clone}
* need to be modified.
* <p>
* ......
*/
//Object类中的clone()方法
protected native Object clone() throws CloneNotSupportedException;
3、深克隆
将原型对象中的所有类型,无论是值类型还是引用类型,都复制一份给克隆对象,也就是说深克隆会把原型对象和原型对象所引用的对象,都复制一份给克隆对象
深克隆是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变
实现Cloneable接口并重写Object类中的clone()方法或者实现Serializable接口,通过对对象的序列化、反序列化实现克隆和字节流输出,通过这三种方式可以实现深克隆
Cloneable接口没有任何方法,仅是个标志接口(tagging interface),若要具有克隆能力,实现Cloneable接口的类必须重写从Object继承来的clone方法,并调用Object的clone方法(见下面Object#clone的定义),重写后的方法应为public的
//Cloneable 接口源码
public interface Cloneable {
}
//重写clone()方法
class CloneClass implements Cloneable{
public Object clone(){
CloneClass o = null;
try{
o = (CloneClass)super.clone();
CloneClass .setAddress(this.address.clone());//引用克隆类型赋值
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return o;
}
}
如果引用类型中海包括引用类型, 要实现多层克隆会很麻烦, 这使用可以使用序列化和反序列化的方式实现对象的深克隆,把对象写到字节流中的过程是序列化的过程, 而把对象从字节流中读出来的过程是反序列化的过程. 由于Java序列化的过程中, 写在流中的是对象的一个拷贝, 而原对象仍然在JVM中
public class A implements Serializable {
private static final long serialVersionUID = "序列化ID"; //显式声明ID
public Outer Aclone() {
Outer outer = null;
try {
// 将对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
// 将流序列化成对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
outer = (Outer) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return outer;
}
}
通过字节流实现深克隆:
/**
* 通过字节流实现克隆
*/
static class StreamClone {
public static <T extends Serializable> T clone(People obj) {
T cloneObj = null;
try {
// 写入字节流
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bo);
oos.writeObject(obj);
oos.close();
// 分配内存,写入原始对象,生成新对象
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());//获取上面的输出字节流
ObjectInputStream oi = new ObjectInputStream(bi);
// 返回生成的新对象
cloneObj = (T) oi.readObject();
oi.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}
}
Java基础——克隆的更多相关文章
- Java基础--对象的克隆
文章转载自https://www.cnblogs.com/Qian123/p/5710533.html 阅读目录 为什么要克隆? 如何实现克隆 浅克隆和深克隆 解决多层克隆问题 总结 假如说你想复制一 ...
- 最适合作为Java基础面试题之Singleton模式
看似只是最简单的一种设计模式,可细细挖掘,static.synchronized.volatile关键字.内部类.对象克隆.序列化.枚举类型.反射和类加载机制等基础却又不易理解透彻的Java知识纷纷呼 ...
- Java基础常见英语词汇
Java基础常见英语词汇(共70个) ['ɔbdʒekt] ['ɔ:rientid]导向的 ['prəʊɡræmɪŋ]编程 OO: object ...
- 【java基础之jdk源码】Object
最新在整体回归下java基础薄弱环节,以下为自己整理笔记,若有理解错误,请批评指正,谢谢. java.lang.Object为java所有类的基类,所以一般的类都可用重写或直接使用Object下方法, ...
- 【JavaEE】企业面试问题-Java基础
1. Java基础部分 1.1 Java中的方法覆盖(Overwrite)和方法重载(Overloading)是什么意思? 重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的 ...
- Java基础(含思维导图)
很早之前整理的Java基础的一些知识点,思维导图: 1.'别名现象' 对一个对象赋值另一个对象,会指向新的对象引用,赋值前的对象引用会由于不再被引用而被gc回收: 而基本类型则不同.基本类型存储了实际 ...
- Java基础系列-ArrayList
原创文章,转载请标注出处:<Java基础系列-ArrayList> 一.概述 ArrayList底层使用的是数组.是List的可变数组实现,这里的可变是针对List而言,而不是底层数组. ...
- Java面试准备之Java基础
1.Java 语言的优点 面向对象,平台无关,内存管理,安全性,多线程,Java 是解释型的 2.Java 和 C++的区别 多重继承(java接口多重,类不支持,C++支持) 自动内存管理 预处理功 ...
- Java英文单词Java基础常见英语词汇
Java英文单词Java基础常见英语词汇(共70个) ...
随机推荐
- 区块链入门到实战(19)之以太坊(Ethereum) – 以太币
以太币的作用:防范以太坊网络被滥用和激励矿工. 与比特币网络有比特币类似,以太坊(Ethereum)也有自己的虚拟币 — 以太币. 以太币的主要作用有2个: 应用程序执行任何操作都需要支付以太币,防范 ...
- 尝试写一写4gl与4fd
4gl DATABASE ds GLOBALS "../../config/top.global" DEFINE g_curs_index LIKE t ...
- Azure Logic App 入门(一)
一,引言 前两天看一个azure相关的题,接触到一个叫 “Azure Logic App” 的服务,刚好,今天抽空学习以下,顺便结合它做一篇入门的分析文章. 首先,我们得对它有个大概的认识,了解以下A ...
- html行内块元素之间的缝隙
关于html行内块元素之间缝隙的那点儿事情 事情是这样子的,我起初打算验证使用transform属性的标签是否会影响其他的标签的布局,于是写了下面一段代码: <!DOCTYPE html> ...
- Redis高可用——副本机制
目录 概念 配置 同步方式 起点 主从握手 部分同步 完全同步 执行完全同步判断条件 完全同步代码实现 为实现Redis服务的高可用,Redis官方为我们提供了副本机制(或称主从复制)和哨兵机制.副本 ...
- 【深入理解Java虚拟机】Java虚拟机运行时数据区
Java虚拟机运行时数据区 线程私有 程序计数器 1.当前线程所执行的字节码的行号指示器. 2.唯一不会发生OutOfMemoryError的区域 3.如果执行的是java方法,计数器值为虚拟机字节码 ...
- lua 优化
彻底解析Android缓存机制——LruCache https://www.jianshu.com/p/b49a111147ee lua:部分常用操作的效率对比及代码优化建议(附测试代码) https ...
- 常用mac命令
~/.bash_profile 可以添加常用的一些命令别名alias unity="open -n /Applications/Unity/Unity.app"
- HOOK SSDK
HOOK SSDT主要代码 #pragma once #include <ntifs.h> /* * * * * * * * * * * * * * * * * * * * * * * * ...
- 100个高频Spring面试题
译 原文:https://www.javacodegeeks.com/2014/05/spring-interview-questions-and-answers.html A:Spring概览 ...