java中克隆,浅拷贝,神拷贝

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

      java中的引用,课本中总是告诉我们jiava中没有指针,其实不然。我们都知道在C++中指针总是带着* 出现的,在java中,指针不再叫指针,叫引用了, 而且指针声明的时候也不再有*了。java中每一个变量的名字就相当与一个引用,指向用new 申请的空间。


    提到java中的克隆,不得不先提一下设计模式中的原型模式。我们举个这样例子,加入你手头上有一份非常好的讲义,这时候,你的朋友也想要一份。难道你要手抄一份吗?当然不是,显然复印的方法来的最直接,简便,而且准去率高。这种用原型来复制而不是重新复制的思维方式就是原型模式的核心思想。我们看一下原型模式的UML图。




java中的克隆就是实现原型模式的一种重要方式,但克隆不等于原型模式。在java中,克隆主要是通过clone()这个实现的,每一个类都会从java.lang.object中继承一个clone()函数。那么这个函数是如何实现的呢。从JDK API 中我们可以了解到clone()方法将调用对象进行复制并返回了一份。并且满足以下条件;

a)对任意一个对象满足x.clone()!=x,也就是x.clone()得到的对象和x引用的内存空间不同

b)x.clone().getClass()=x.getClass(),x.clone()的到的对象和x两个对象是一个类,即二者类型一致

c)大部分情况下还满足,x.clone().equal(x)。这个地方我不太了解。

那么clone()函数是怎么实现呢,先看代码如下

public class Point implements Cloneable {
public int a_pos;
public int b_pos;
Point()
{
	a_pos=10;
	b_pos=15;
}
public Object clone()
{
	Object o=null;
	try {
		o=(Point)super.clone();
	} catch (CloneNotSupportedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return o;	
}
}
public class MainTest {

	public static void main(String args[]){
	Point a=new Point();
	System.out.println(a.a_pos+" "+a.b_pos);
	Point b=(Point) a.clone();
	System.out.println(b.a_pos+" "+b.b_pos);
	System.out.println("a.equals(b) is "+ a.equals(b));
	System.out.println("a!=b is "+ (a!=b));
	System.out.println("a.getClass()==b.getClass() is "+ (a.getClass()==b.getClass()));
	}	
}
打印出来显示
10 15
10 15
a.equals(b) is false
a!=b is true
a.getClass()==b.getClass() is true
说明了对象a和b指向了不同的内存,也就是说对象在克隆的时候,是将对象a引用的内存进行了内存的复制,然后放到了新的内存中。那么什么叫浅拷贝呢,其实如果所有的类通过实现cloneable接口并重写clone()是可以有效避免浅拷贝的(个人观点,也许有误,请指正)
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;


public class Point implements Serializable {
public int a_pos;
public int b_pos;
Point()
{
	a_pos=10;
	b_pos=15;
}
public Object deepClone() throws Throwable
{
	ByteArrayOutputStream bo=new ByteArrayOutputStream();
	ObjectOutputStream oo=new ObjectOutputStream(bo);
	oo.writeObject(this);			                       //write the object into the stream
	ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
	ObjectInputStream oi=new ObjectInputStream(bi);
	return(oi.readObject());
}
}
如有不对之处,请指正不胜感激
Java对象克隆方法:深入解析浅拷贝与深拷贝的实现方案 对象克隆Java编程中用于创建对象的精确副本,主要分为浅拷贝和深拷贝浅拷贝仅复制对象本身,引用类型共享,适用于无嵌套可变对象的场景,实现简单且性能高。深拷贝则复制对象及其引用对象,适用于含嵌套可变对象的场景,实现复杂且性能较低。深拷贝可通过序列化或递归克隆实现,序列化方式简单但性能差,递归克隆性能好但实现复杂。选择克隆方法时需考虑对象结构、性能需求和实现复杂度等因素。 阅读详情

相关推荐

为什么要使用克隆?如何实现对象克隆?深拷贝浅拷贝区别是什么?

为什么要使用克隆?如何实现对象克隆?深拷贝浅拷贝区别是什么?

javamyfriend的博客 1762

拷贝的五种实现方式

拷贝的几种实现方式

Z_J_CSDN的博客 3万+

拷贝浅拷贝

拷贝浅拷贝

lydms的博客 7461

拷贝

拷贝 一、什么是深拷贝?(先简单理解概念) 深拷贝是指,拷贝对象的具体内容,深拷贝在计算机中开辟一块新的内存地址用于存放复制的对象。源数据改变不会影响复制的数据。 二、为什么要使用深拷贝? 我们希望在改变新的数组(对象)的时候,不改变原数组(对象) arr=[100,[{a:'hello'},{b:"world"}],{c:"123456789"}]; //判断修改的是不是'object'或者null,如果不是object或者null那么直接返回 f...

shiqianhui1124的博客 5729

拷贝浅拷贝

浅拷贝和深拷贝

yujiabao702的博客 2042

JavaScript深拷贝看这篇就行了!(实现完美的ES6+版本)

本版本的深拷贝考虑了Symbol作为对象属性的情况(Symbol相关介绍看这:Symbol)。 由于引用类型在赋值时只传递指针,这种拷贝方式称为浅拷贝。 而创建一个新的与之相同的引用类型数据的过程称之为深拷贝。 在JavaScript中,基础类型值的赋值是直接拷贝一份新的一模一样的数据,这两份数据相互独立,互不影响。而引用类型值(对象类型)的赋值是传递对象的引用(也就是对象所在的内存地址,即指向对象的指针),相当于多个变量指向同一个对象,那么只要其中的一个变量对这个对象进行修改,其他的变量所指向的对象也

码飞_CC的博客 3万+

【轻松拿捏】java中为什么要使用克隆?如何实现对象克隆?深拷贝浅拷贝区别是什么?

浅拷贝:只复制对象本身及其基本类型成员变量,引用类型成员变量仍然指向原对象的引用。深拷贝:递归复制对象及其所有层次的成员变量,创建完全独立的新对象。选择使用哪种拷贝方式取决于具体需求和对象的复杂性。在需要完全独立的副本时,使用深拷贝;在只需要复制表层结构时,使用浅拷贝

边走、边悟、迟早变好 2816

Java对象克隆-浅拷贝与深拷贝

JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。克隆的是两个不同的对象。

棉花糖老丫 1715

Java 浅拷贝与深拷贝

1、什么叫Java浅拷贝?  浅拷贝是会将对象的每个属性进行依次复制,但是当对象的属性值是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化。 2、什么叫Java拷贝?  深拷贝复制变量值,对于引用数据,则递归至基本类型后,再复制。深拷贝后的对象与原来的对象是完全隔离的,互不影响,对一个对象的修改并不会影响另一个对象。 3、Java浅拷贝和深拷贝的区别是什么?  通俗来讲浅拷贝的复...

u011035026的博客 8990

Java 对象的克隆Clone和必须了解的浅拷贝与深拷贝

前言 为什么要写这篇文章? 因为我最近无意间看到了一些项目的代码,不管是曾经编码的人还是新接手的人, 在想完全克隆复制一个已经存在的对象,做为后续的使用,竟然都是采取了重写new一个,然后一个个属性字段值get出来再set回去,这种代码段让我不禁陷入了沉思。 简单描述下场景: 已经存在一个对象 sheep,里面已经有了一些字段属性值; 因为业务处理需要,想整一个跟这个sheep 对象一模一样的 sheep2 出来; 然后在不管是使用sheep 或者 sheep2 的时候,都互不干扰。 ..

默默不代表沉默 2573

java克隆(clone),浅拷贝和深拷贝的区别

在很多人初学的时候,一定会被克隆是什么?怎么使用克隆浅拷贝和深拷贝又是啥?所搞得晕头转向。这里我希望用最简单的语言向大家介绍我自己的理解。(我们马克思老师说,你能不能用农民也听得懂的语言介绍一下这个知识。)

m0_49425260的博客 2154

Java中的深拷贝浅拷贝

浅拷贝:对基本类型数据进行值传递,对引用类型数据进行引用传递的拷贝拷贝:对基本类型数据进行值传递,对引用类型数据创建一个新的对象,并复制其内容在Java中,所有的对象都继承自,在类中提供了一个方法来供我们对Java对象进行拷贝: 这个方法是的,所以不需要我们来实现。不过需要注意的是,这个方法还是的,这意味着方法只在包或其子类可见。方法还抛出了一个异常,通过源码注释可以知道,当调用了方法的对象类没有实现接口,或者无法克隆对象的时候,会抛出该异常,也就是说,如果要成功的调用接口,首先该类要实现接口。 Clon

qq_43460095的博客 6740

JAVA对象的拷贝/克隆(“浅拷贝、深拷贝“) 浅析

根据结果我们可以以看出,“”先借着a对象创造了一个b对象,这里改完b对象的猫猫的名字为“yiyi”后,由测试结果我们可以看出,“”先借着a对象创造了一个b对象,这里改完b对象的猫猫的名字后,方法是一个受保护的方法,它执行对象的浅拷贝。,默认情况下,`Object` 类中提供的 `clone()` 方法执行。测试的步骤和第一个方法是一样的,但是结果却是不一样的哦!虽然是好用但是是有缺点的,让我们看看为啥(测试结果)吧!a,b俩人终于不是养的同一只猫了,而是两只不一样的!方法,它是实现对象拷贝的基础。

zjx030816的博客 2167

拷贝浅拷贝克隆和浅克隆

拷贝浅拷贝是用来描述对象或者对象数组这种引用数据类型的复制场景的。浅拷贝,就是只复制某个对象的指针,而不复制对象本身。这种复制方式意味着两个引用指针指向被复制对象的同一块内存地址。深拷贝,会完全创建一个一模一样的新对象,新对象和老对象不共享内存,也就意味着对新对象的修改不会影响老对象的值。在Java里面,无论是深拷贝还是浅拷贝,都需要通过实现Cloneable接口,并实现clone()方法。然后我们可以在clone()方法里面实现浅拷贝或者深拷贝的逻辑。

刘皇叔说Java的博客 1601

一文道破Java中的深拷贝浅拷贝,零拷贝

Java编写代码中,对象的拷贝是一个常见的操作。根据拷贝的层次和方式不同,可以分为深拷贝浅拷贝和零拷贝。本篇文章我们将详细介绍这三种拷贝方式的概念、实现方法以及使用场景,方便大佬学习及面试。

小威的博客 1万+

Java 克隆技术详解,深拷贝浅拷贝的区别及实现

克隆是指创建一个对象的副本,使得新创建的对象在内容上与原始对象相同。在编程中,克隆是常用的技术之一,它具有以下几个重要用途和优势:复制对象:使用克隆可以创建一个与原始对象相同的新对象,包括对象的属性和状态。这样可以在不影响原始对象的情况下,对新对象进行修改、操作、传递等。这在某些场景下非常有用,可以避免重新创建和初始化一个对象。隔离性与保护:通过克隆,可以创建一个独立于原始对象的副本。这样,修改克隆对象时,不会影响到原始对象,从而实现了对象之间的隔离性。

兴趣是最好的老师,勤能补拙 1549

Java中的深拷贝浅拷贝

实现Cloneable标记接口重写Object类中的clone方法捕获处理或抛出使用clone方法带来的异常将克隆猴返回的Object类型的对象向下转型为克隆类型如果克隆对象的内部还有引用类型,则需要对内部的引用类型也按照上述1,2,3步骤在自己的clone方法中进行克隆返回。

小S的博客 1943

Java的深拷贝浅拷贝的区别

1.二者的区别 浅拷贝:在拷贝一个对象时,对对象的基本数据类型的成员变量进行拷贝,但对引用类型的成员变量只进行引用的传递,并没有创建一个新的对象,当对引用类型的内容修改会影响被拷贝的对象。 深拷贝:在拷贝一个对象时,除了对基本数据类型的成员变量进行拷贝,对引用类型的成员变量进行拷贝时,创建一个新的对象来保存引用类型的成员变量。 2.浅拷贝和深拷贝的应用 浅拷贝 java中clone方法是一个浅拷贝,引用类型依然在传递引用 深拷贝 ...

蜡笔小贤的博客 1万+
上一篇: 从GetMemory()看C/C++内存分配机制
下一篇: Python学习-格式化输出(format)
ysh512
博客等级 码龄17年 4粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值