纸上得来终觉浅,绝知此事要躬行
 --陆游    
问渠那得清如许,为有源头活水来  --朱熹

clone和Copy:当有一个对象Person p1=new Person("name",age);Person p2=p1;此时只是简单的copy了一下引用,p1和p2都指向了内存中的同一个对象,修改p1和p2中任何一个都会影响到对方。当函数的参数是对象时,传递的是引用类型,在对象函数内部的操作会影响到外边对象。如果希望传递的是对象的一个拷贝时,这时就需要用到object的clone()方法。)拷贝对象返回的是一个新对象,而不是引用;拷贝对象与new操作符返回的新对象的区别就是这个拷贝对象已经包含了原来对象的一些信息,而不是对象的初始信息。什么时候使用shallow
Clone(浅拷贝,影子拷贝),什么时候使用deep Clone(深拷贝):主要看具体域对象的性质是什么,如果是基本类型使用shallow Clone,如果是reference
variable(引用变量)使用deep Clone。
实现克隆的步骤:
(1)实现Cloneable接口,Cloneable没有任何抽象方法,称为标志接口。
(2)覆盖基类 的clone方法,并声明为public
(3)在派生类中重写clone方法,并调用super.clone()     
在clone中分为浅拷贝和深拷贝,浅拷贝就是不管参数是基本类型还是引用类型,直接调用super.clone()进行拷贝,结果引用类型还是指向相同的内存;深拷贝就是在调用super.clone()之后,还要调用引用参数的clone()函数,进行拷贝,来达到深拷贝。
 

浅拷贝:

(1) 基本的数据类型(String)是会拷贝复制一份新的对象

(2)引用对象还是引用同一份对象。

浅拷贝示例代码:

public class Info {
public int idnumber;
public int getIdnumber() {
return idnumber;
}
public void setIdnumber(int idnumber) {
this.idnumber = idnumber;
}
}
public class Person implements Cloneable{
private int age;
private String nameString;
public Info info;
public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNameString() {
return nameString;
}
public void setNameString(String nameString) {
this.nameString = nameString;
}
public String toString()
{
return "name:"+nameString+",age:"+age+",idnumber"+info.idnumber;
}
public Object clone()
{
Person person=null;
try {
person=(Person)super.clone(); //浅拷贝
//person.info=(Info)info.clone();
} catch (CloneNotSupportedException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
return person;
}
}

public class Hello {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Info info=new Info();
info.setIdnumber(100);
Person person1=new Person();
person1.setAge(10);
person1.setNameString("tiantian");
person1.info=info;
Person person2=(Person)person1.clone();
person2.setNameString("hello");
person2.setAge(20);
person2.info.setIdnumber(200);
System.out.println("person2"+person2);
System.out.println("person1"+person1);
}

}

最后的结果是:

person2name:hello,age:20,idnumber200
person1name:tiantian,age:10,idnumber200

person1和person2的基本类型name和age都改变了,但引用类型的idnumber数值没变。

深拷贝:

(1)对存在的引用类型也进行拷贝,浅拷贝与深拷贝的代码还是有不同点的。

深拷贝代码示例:

public class Info implements Cloneable {//Info也进行拷贝
public int idnumber;
public int getIdnumber() {
return idnumber;
}
public void setIdnumber(int idnumber) {
this.idnumber = idnumber;
}
public Object clone()
{
Info info=null;
try {
info=(Info)super.clone();
} catch (CloneNotSupportedException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
return info;
}
}

public class Person implements Cloneable{

private int age;
private String nameString;
public Info info;

public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
public Person() {
// TODO 自动生成的构造函数存根

}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNameString() {
return nameString;
}
public void setNameString(String nameString) {
this.nameString = nameString;
}

public String toString()
{
return "name:"+nameString+",age:"+age+",idnumber"+info.idnumber;
}

public Object clone()
{
Person person=null;
try {
person=(Person)super.clone(); //浅拷贝
person.info=(Info)info.clone();//加上这一句就变成了深拷贝,对对象引用也进行一次拷贝
} catch (CloneNotSupportedException e) {
// TODO 自动生成的 catch
e.printStackTrace();
}
return person;
}
}

结果:

person2name:hello,age:20,idnumber200
person1name:tiantian,age:10,idnumber100

所有的值都进行了改变。

Java-clone总结的更多相关文章

  1. java Clone之深浅拷贝

    要点: 1.浅度拷贝可以不实现Cloneable接口(自动使用Object.clone)或者不重写Cloneable的clone方法. 2.要被深度拷贝的类必须实现Cloneable接口并重写clon ...

  2. Java clone() 方法克隆对象——深拷贝与浅拷贝

    基本数据类型引用数据类型特点 1.基本数据类型的特点:直接存储在栈(stack)中的数据 2.引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里 引用数据类型在栈中存储了指针,该指 ...

  3. java Clone使用方法详解

    java"指针"       Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念.并且由于Java不能 通过 ...

  4. java clone简单学习

    最近在帮忙写单侧的时候,经常会和这几个对象类打交道,因为对java也不是很熟悉,刚好学习一下,都是很浅的学习,并没有深入的去学习哈,因为感觉也用不上. protected Object clone() ...

  5. java Clone()克隆

    转自:http://www.blogjava.net/orangelizq/archive/2007/10/17/153573.html 现在Clone已经不是一个新鲜词语了,伴随着“多莉”的产生这个 ...

  6. java clone()

    Java中对象的创建   clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象 ...

  7. JAVA Clone复制对象

    谈到了对象的克隆,就不得不说为什么要对对象进行克隆.Java中所有的对象都是保存在堆中,而堆是供全局共享的.也就是说,如果同一个Java程序的不同方法,只要能拿到某个对象的引用,引用者就可以随意的修改 ...

  8. 再谈java clone 以及 浅/深拷贝

    简单对象的拷贝,直接使用其clone方法 即可, 不会有什么问题: class Dog implements Cloneable public Dog clone() { int age; Strin ...

  9. Java clone() 浅克隆与深度克隆(转)

    以下文字转自:桔子园 http://www.blogjava.net/orangelizq/archive/2007/10/17/153573.html 现在Clone已经不是一个新鲜词语了,伴随着“ ...

  10. Java clone方法(下)

    1.终于调用的是一个JNI方法,即java本地方法,加高速度 2.使用clone方法,分为浅复制.深复制,这里直接使用网上抄来的案例来说明吧: 说明: 1)为什么我们在派生类中覆盖Object的clo ...

随机推荐

  1. 豌豆夹Redis解决方案Codis源码剖析:Dashboard

    豌豆夹Redis解决方案Codis源码剖析:Dashboard 1.不只是Dashboard 虽然名字叫Dashboard,但它在Codis中的作用却不可小觑.它不仅仅是Dashboard管理页面,更 ...

  2. pthon核心编程-读书笔记:知识点摘录与总结(方便理解和快速记忆)

    Python 中的列表(大小可变的数组)和字典(哈希表)就是内建于语言本身的.在核心语言中提供这些重要的构建单元,可以鼓励人们使用它们, 缩短开发时间与代码量,产生出可读性更好的代码.C不提供, c+ ...

  3. PHP学习(2)——运行环境搭建

    学习PHP首先要搞定PHP的运行环境.PHP的运行环境包括:PHP语言解析器本身以及Apache服务器.MySQL数据库等.因为只是学习嘛,尽快的搭建起来运行环境就好,到后期慢慢懂得多了再去想规范化搭 ...

  4. 关于[[NSNotificationCenter defaultCenter] addObserver不remove后续又收到通知crash问题

    今天试了一个小demo,测出一个现象,同步出来:object 作为 observer 监听了通知 A,然后 object 中途被释放执行了dealloc,随后app发出这个通知 A:iOS 6.iOS ...

  5. ERROR: In <declare-styleable> MenuView, unable to find attribute android:preserveIconSpacing

    eclipse  sdk从低版本切换到高版本sdk的时候   v7包会包这个错ERROR: In <declare-styleable> MenuView, unable to find ...

  6. UE4联机多人游戏基本设置

    UE4自带网络联机功能,但是似乎只有蓝图接口,而真正写功能的时候不能用C++,让人感觉相当诡异 还是作一个简单记录 1.建一个第三人称模板,为什么会用他呢,因为它自带模板的很多组件,直接支持联机功能, ...

  7. Linux内核编译时会遇到的问题--缺少mkimage

    由于各大平台所带的内核不同,所以编译方式也不同,但方法都是大同小异. 但是,编译内核有时候会提示缺少mkimage这个命令,如何解决? 供应商提供内核的同时也会提供其它的一些,比如Uboot,root ...

  8. ubuntu14.04使用root用户登录桌面

    ubuntu安装好之后,默认是不能用root用户登录桌面的,只能使用普通用户或者访客登录.怎样开启root用户登录桌面呢? 先用普通用户登录,然后切换到root用户,然后执行如下命令: vi /usr ...

  9. 再谈机器学习中的归一化方法(Normalization Method)

    机器学习.数据挖掘工作中,数据前期准备.数据预处理过程.特征提取等几个步骤几乎要花费数据工程师一半的工作时间.同时,数据预处理的效果也直接影响了后续模型能否有效的工作.然而,目前的大部分学术研究主要集 ...

  10. ubuntu16.04中可以用于教学的有趣的应用

    ubuntu16.04中可以用于教学的有趣的应用 在ubuntu自带的软件中心里,内置了非常丰富的教育应用,可以用于物理,化学等科学课教学,只选取我用过用于教学的软件,优秀的软件不止这些,可以慢慢发掘 ...