Java深复制和浅复制

  Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别。并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象。本文会让你了解什么是影子clone(浅复制)与深度clone(深复制),认识它们的区别、优点及缺点。

  Java语言取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写成的代码不亚于使用早已臭名昭著的”GOTO”语句。Java放弃指针的概念绝对是极其明智的。但这只是在Java语言中没有明确的指针定义,实质上每一个new语句返回的都是一个指针的引用,只不过在大多时候Java中不用关心如何操作这个”指针”,更不用象在操作C++的指针那样胆战心惊。唯一要多多关心的是在给函数传 递对象的时候。

  Java对对象和基本的数据类型的处理是不一样的。和C语言一样,当把Java的基本数据类型(如int,char,double等)作为入口参数传给函数体的时候,传入的参数在函数体内部变成了局部变量,这个局部变量是输入参数的一个拷贝,所有的函数体内部的操作都是针对这个拷贝的操作,函数执行结束后,这个局部变量也就完成了它的使命,它影响不到作为输入参数的变量。这种方式的参数传递被称为”值传递”。而在Java中用对象作为入口参数的传递则缺省为”引用传递”,也就是说仅仅传递了对象的一个”引用”,这个”引用”的概念同C语言中的指针引用是一样的。当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。除了在函数传值的时候是”引用传递”,在任何用”=”向对象变量赋值的时候都是”引用传递”。就是类似于给变量再起一个别名。两个名字都指向内存中的同一个对象。

  在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在Java语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段。

  Java的所有类都默认继承java.lang.Object类,在java.lang.Object类中有一个方法clone()。JDKAPI的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。

浅复制:

  被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象地址。就是说:浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

深复制:

  被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象地址,而不再是原有的那些被引用的对象地址。就是说,深复制把要复制的对象所引用的对象都复制了一遍。

两种实现方式:

  1. 实现Cloneable接口并重写clone方法

  2. 实现序列化接口Serializable


源代码地址

猜你喜欢

转载自blog.csdn.net/panchao888888/article/details/80996423