对象克隆

对象克隆又称为对象复制,从一个对象克隆出另一个新对象,新对象的属性值和原来相同。相当于new一个对象,然后将属性一个个赋给新对象,只不过我们可以使用clone方法来取代这个过程。根据克隆深度的不同,分为如下

克隆实现分为三步

1. 需要克隆的对象实现Cloneable接口,Cloneable只是一个标志,没有任何需要实现的方法

2. 在该对象中重写父类的clone方法

2. 在clone方法中调用super.clone(),实际是调用Object中的clone方法

1. 浅层复制

浅层复制指只克隆对象的基本类型属性,而不克隆引用类型属性。比如一个User对象中有一个属性为Student对象类型,那么复制后,新对象的student属性的引用和原对象student的属性引用相同,修改student的属性会互相影响。

为压缩不必要的代码,下面属性访问权限直接使用public来处理

// Student类
class Student{
    public String stuName;
}

// User类,实现Cloneable接口
class User implements Cloneable{
    public int id;
    public Student stu;

    public User(int id, Student stu) {
        this.id = id;
        this.stu = stu;
    }

    // 重写clone方法
    @Override
    protected User clone() throws CloneNotSupportedException {
        return (User) super.clone();// 调用Object中的clone方法
    }
}

//测试类
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student stu = new Student();
        stu.stuName = "测试";
        User u1 = new User(1, stu);
        // 克隆
        User u2 = (User) u1.clone();
        // 修改u1中stu的属性stuName为1
        u1.stu.stuName = "1";
        // u2中stu的stuName也变为1
        System.out.println(u2.stu.stuName);// 输出1
    }
}

2. 深层复制

深层复制指即克隆基本类型属性,又克隆引用类型属性。还是上面的例子,如何做到修改u1.stu.stuName的属性,而不影响u2.stu.stuName的属性呢?我们将上面的例子改造下,通过让Student实现克隆接口和重写克隆方法,修改User的克隆方法来处理。

// Student类,实现Cloneable接口
class Student implements Cloneable{
    public String stuName;

    // 重写clone方法
    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }
}

// User类,实现Cloneable接口
class User implements Cloneable{
    public int id;
    public Student stu;

    public User(int id, Student stu) {
        this.id = id;
        this.stu = stu;
    }

    // 重写clone方法
    @Override
    protected User clone() throws CloneNotSupportedException {
        // 克隆一个新对象
        User user = (User) super.clone();
        // 克隆原对象stu属性
        Student stu = this.stu.clone();
        // 将克隆的stu属性赋给新对象
        user.stu = stu;
        // 返回新对象
        return user;
    }
}

//测试类
public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student stu = new Student();
        stu.stuName = "测试";
        User u1 = new User(1, stu);
        // 克隆
        User u2 = (User) u1.clone();
        // 修改u1中stu的属性stuName为1
        u1.stu.stuName = "1";
        // u2中stu的stuName也变为1
        System.out.println(u2.stu.stuName);// 输出不变,还是"测试"
    }
}
时间: 2024-08-10 15:08:13

对象克隆的相关文章

C# 对象克隆,DataTable转LIST

public class ConvertHelper<T> where T : new() { private static string module = "ConvertHelper.cs"; public static ObservableCollection<T> ConvertToList(List<T> listobject) { ObservableCollection<T> collection = null; try {

[Java学习笔记]对象克隆

对象克隆: 浅克隆: 被克隆的对象中的值类型数据被复制一份新值,但是引用的对象只被复制其引用传递给新克隆出来的对象 深克隆: 被克隆的对象中的值类型数据被复制一份新值,并且其中引用的对象会重新创建新的对象,把新对象的引用传递给新克隆出来的对象 Java中实现克隆: Java中Object中定义了clone方法,默认为浅克隆操作,即你只是简单super.clone得到的结果是浅克隆的结果,如果需要深克隆,则需要实现Cloneable接口,并且重写clone方法 查看Java源代码发现Object中

C#对象克隆介绍

浅拷贝和深拷贝 有两种对象克隆的方法:浅拷贝和深拷贝.浅拷贝只是复制引用,而不会复制引用的对象.深拷贝会复制引用的对象. 因此,原始对象中的引用和浅拷贝对象中的同一个引用都指向同一个对象.而深拷贝的对象包含了对象的一切直接或间接的引用.参看维基百科(http://en.wikipedia.org/wiki/Object_copy)来获得更多解释. ICloneable接口 ICloneable接口包含一个Clone方法,可以用来创建当前对象的拷贝. public interface IClone

Java提高篇——对象克隆(复制)

阅读目录 为什么要克隆?如何实现克隆浅克隆和深克隆解决多层克隆问题总结 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况. 但是如果你复制的是一个对象,情况就有些复杂了. 假设说我是一个beginner,我会这样写: class Student { private int number; pu

对象引用与对象克隆

对象克隆就是在原先对象的基础上,再复制一份,克隆的属性与原先的一模一样,但是是两个对象,之后对这两个对象的任何操作都不会影响到对方.要想将某个对象克隆,必须实现Cloneable接口,然后还需要复写Object类的clone方法. 对象引用其实是多个索引对同一个对象的引用,不管谁改变了对象的属性,对象都会改变,其他索引再访问时,属性已经变了 像函数式编程,对象的操作都是无副作用的,不会改变对象的状态,类似于对象克隆,就是把对象再复制一份,原先的对象不动,只需要使用复制的那个对象即可.而原始的ja

对象克隆实例

A.java package second; public class B { public static void main(String[] args){ C c = new C(); c.i = 200; c.haha(); System.out.println("=========="); C cl = (C)c.clone(); cl.i = 500; cl.haha(); c.haha(); } } B.java package second; class C implem

jquery动态添加删除div--事件绑定,对象克隆

我想做一个可以动态添加删除div的功能.中间遇到一个问题,最后在phpchina问答区版主的热心帮助下解答了(答案在最后)        使用到的jquery方法和思想就是:事件的绑定和销毁(unbind),另外还可以使用clone,通过克隆可以很好的解决这个问题          相关描述如下 功能:点击增加,自动添加一个iptdiv 点击 iptdiv后的 X 自动删除当前div 问题:默认存在的(也就是页面加载进来的)的那个iptdiv 后的 X 点击有效,可以删除当前 iptdiv  但

Java对象克隆了解

1.java接口中有一种空的接口叫标识接口,这种接口值起到标识作用. 2.要实现java对象克隆需要用到Object类的 protected Object clone() throws CloneNotSupportedException    方法,这个方法为protected限定,在本包中,或者不同包的子类中才能访问,并且抛出异常. 3.如果要实现对象克隆首先被克隆的类必须实现Cloneable接口,如果没有实现这个接口,调用clone()方法会抛出 CloneNotSupportedExc

Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨

Java对象克隆(Clone)及Cloneable接口.Serializable接口的深入探讨 Part I 没啥好说的,直接开始Part II吧. Part II 谈到了对象的克隆,就不得不说为什么要对对象进行克隆.Java中所有的对象都是保存在堆中,而堆是供全局共享的.也就是说,如果同一个Java程序的不同方法,只要能拿到某个对象的引用,引用者就可以随意的修改对象的内部数据(前提是这个对象的内部数据通过get/set方法曝露出来).有的时候,我们编写的代码想让调用者只获得该对象的一个拷贝(也