如果一个待拷贝的对象域中含有引用类型,使用默认的clone方法,必然不能将引用类型的域值重新“生成”一个,原因在于,引用类型存放的是某个堆内对象的地址。JAVA默认的clone方法是浅拷贝,也就是说,新生成的那个对象的引用类型只是把待拷贝对象的地址又拷贝了一遍,于是乎,clone前和clone后的对象关于引用域值的属性必然指向了同一块内存(对象)。这种结果并不是我们真正想要的拷贝结果,因为如果修改clone前的域值,clone后对象的域值也会相应变化,就不一是一般意义上的“克隆”了。要想改变这个情况,必须要程序员对想要拷贝对象中重新声明clone方法,如下例红色部分。
import java.util.*;
public class CloneTest
{
public static void main(String[] args)
{
try
{
Employee original = new Employee("John Q. Public", 50000);
original.setHireDay(2000, 1, 1);
Employee copy = original.clone();
copy.raiseSalary(10);
copy.setHireDay(2002, 12, 31);
System.out.println("original=" + original);
System.out.println("copy=" + copy);
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
}
}
class Employee implements Cloneable
{
public Employee(String n, double s)
{
name = n;
salary = s;
}
[b] public Employee clone() throws CloneNotSupportedException
{
// call Object.clone()
Employee cloned = (Employee)super.clone();
// clone mutable fields
[color=red] cloned.hireDay = (Date)hireDay.clone();[/color]
return cloned;
}[/b]
/**
Set the hire day to a given date
@param year the year of the hire day
@param month the month of the hire day
@param day the day of the hire day
*/
public void setHireDay(int year, int month, int day)
{
hireDay = new GregorianCalendar(year, month - 1, day).getTime();
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
public String toString()
{
return "Employee[name=" + name
+ ",salary=" + salary
+ ",hireDay=" + hireDay
+ "]";
}
private String name;
private double salary;
private Date hireDay;
}
如此这般,clone方法便不是浅拷贝了,是真正意义上的“克隆”了。
分享到:
相关推荐
今天小编就为大家分享一篇关于Java Clone深拷贝与浅拷贝的两种实现方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
java设计模式【之】原型模式、深拷贝与浅拷贝【源码】【场景:克隆羊】 * 原型模式(Prototype) * 实现方式: * 需要被克隆的 class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 ...
目录一、深拷贝与浅拷贝解析浅拷贝深拷贝二、数组拷贝的方式1.for循环来拷贝2.System.arraycopy( )拷贝3.Arrays.copyOf( )拷贝4.clone( )拷贝5.解释三、四种拷贝方式效率比较1. System.arraycopy( )2.Arrays.copyOf...
1、定义 原型模式(Prototype)是通过复制一个已经存在的实例来返回新的实例,而不是新建实例,被复制的实例是我们所称的... (1)利用Java中的clone方法深拷贝与浅拷贝 浅拷贝: public class Professor { pri
主要介绍了java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
本文将会深入的探讨一下在拷贝对象中会出现的浅拷贝和深拷贝的情况。 拷贝接口 java中所有的对象都是继承自java.lang.Object。Object对象中提供了一个clone方法,来供我们对java对象进行拷贝。 protected native ...
(抱歉,我无法修改下载积分,本想着免积分的)C#浅拷贝(MemberwiseClone等多种方法)与深拷贝(反射、多种反序列化)实例
浅拷贝(浅复制、浅克隆)、深拷贝(深复制、深克隆)实战工程,IDEA搭建
本文实例讲述了JavaScript对象的浅拷贝和深拷贝。分享给大家供大家参考,具体如下: 1、浅拷贝 仅仅复制对象的引用,而不是对象本身。 var person = { name: 'Alice', friends: ['Bruce', 'Cindy'] } var student...
Java深浅clone测试代码 流拷贝 Cloneable
java中clone的详细用法,分浅拷贝和深拷贝,并分别有详细的实例介绍。从原理分析。
主要介绍了Java中实现深拷贝的两种方式—clone() & Serialized,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
重写clone()方法,因为Object的clone()的修饰符是protected; @HotSpotIntrinsicCandidate protected native Object clone() throws CloneNotSupportedException; 实现Cloneable接口,否则会抛出...
java中clone的详细用法,分浅拷贝和深拷贝,并分别有详细的实例介绍。从原理分析。
对象的深拷贝与浅拷贝的区别如下: 浅拷贝:仅仅复制对象的引用,而不是对象本身; 深拷贝:把复制的对象所引用的全部对象都复制一遍。 一. 浅拷贝的实现 浅拷贝的实现方法比较简单,只要使用是简单的复制语句即可。...
一、List对象中的T是值类型的情况(int 类型等) 对于值类型的List直接用以下方法就可以复制: List<T> oldList = new List(); oldList.Add(..); List<T> newList = new List... public static IList<T> Clone(t
与深拷贝相对的就是浅拷贝,很多初学者在接触这个感念的时候,是很懵逼的。 为啥要用深拷贝? 在很多情况下,我们都需要给变量赋值,给内存地址赋予一个值,但是在赋值引用值类型的时候,只是共享一个内存区域,...
List的深度复制 浅谈C#中List<T>对象的深度拷贝问题
12. 深拷贝与浅拷贝 13. 防抖和节流 14. 作用域和作用域链、执行期上下文 15. DOM常见的操作方式 16. Array.sort()方法与实现机制 17. Ajax 17. 垃圾回收 18.JS中的String和Math方法 ······
传统的深拷贝做法 JSON.parse(JSON.stringify(data)) 递归浅拷贝 第一种做法存在一些局限,很多情况下并不能使用,因此这里就不提了;第二种做法一般是工具库中的深拷贝函数实现方式,比如 loadash 中的 cloneDeep。...