Java对象复制和数组复制(拷贝)

在实现原型模式时需要拷贝对象,于是……

浅拷贝:只复制一个对象,对象内部存在的指向其他对象数组或者引用则不复制

深拷贝:对象,对象内部的引用均复制

对象拷贝

一、对象浅拷贝

Object类里的clone方法是浅复制

1. 实现Cloneable接口,该接口没有任何方法和字段实现仅供标记使用。不实现会抛出CloneNotSupportedException

2. 覆盖clone方法,权限设为public,并在方法内调用super.clone()

 

public class CloneTest {
    public static void main(String[] args) {
        Address address=new Address();
        Student student = new Student();
        student.setAddress(address);
        Student student1=student.clone();
        System.out.println(student==student1);
        System.out.println(student.getAddress()==student1.getAddress());
    }
}


public class Address{
      private String addr;
}


public class Student implements Cloneable{
    private int age;
    private String name;
    private Address address;
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address= address;
    }
    @Override
    publicStudent clone() {
      Student stu=null;
        try {
            stu= (Student) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return stu;
    }
}

 

二、对象深拷贝

方法一:

覆盖此对象的clone方法、覆盖此对象内部的引用对象的clone方法,然后在此对象的clone方法内调用对象内部的引用对象的clone方法,并set进自己的字段里。

此项不写,参考java.util.Date 的深复制clone

public Object clone() {
    Date d = null;
    try {
        d = (Date)super.clone();
        if (cdate!= null) {
            d.cdate = (BaseCalendar.Date)cdate.clone();
        }
    } catch (CloneNotSupportedException e) {}// Won't happen
    
returnd;
}

方法二:

使用Serializable接口

此对象以及所有需要复制的此对象内部所引用的对象都要实现Serializable接口,该接口没有任何方法实现同样仅供标记使用()

最好加上public static final long serialVersionUID=4545154351L;

只需覆盖此对象的clone方法,权限设为public,内部引用对象不需要覆盖

public class CloneTest {
    public static void main(String[] args) {
        Address address=new Address();
        Student student = new Student();
        student.setAddress(address);
        Student student1=student.clone();

        System.out.println(student.getAddress()==student1.getAddress());
    }
}

import java.io.Serializable;
public class Address implements Serializable{
    public static final long serialVersionUID=4545154351L;
    private String addr;
}

import java.io.*;

public class Student implements Serializable{
    public static final long serialVersionUID=45451511351L;
    private int age;
    private String name;
    private Address address;
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address= address;
    }
    @Override
    publicStudent clone() {
        Student stu=null;
        try {
            ByteArrayOutputStream byteArrayOutputStream=newByteArrayOutputStream();
            ObjectOutputStream objectOutputStream=newObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(this);
            ByteArrayInputStream bis=newByteArrayInputStream(byteArrayOutputStream.toByteArray());
            ObjectInputStream objectInputStream = newObjectInputStream(bis);
            stu= (Student) objectInputStream.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return stu;
    }
}

数组拷贝

System.arraycopy() 浅拷贝

public static void arraycopy(Object src,  int srcPos,  Object dest,  int destPos,   int length)

从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。

参数:

src - 源数组。

srcPos - 源数组中的起始位置。

dest - 目标数组。

destPos - 目标数据中的起始位置。

length - 要复制的数组元素的数量。

例如: 自我复制 删除threads[i]元素

System.arraycopy(threads, i +1, threads, i, --nthreads- i);

Arrays.copyOfSystem.arraycopy的区别?大的区别是没有的,因为Arrays.copyOf内部调用了System.arraycopy

详细用法见

http://blog.csdn.net/csdn9988680/article/details/78160094

猜你喜欢

转载自blog.csdn.net/csdn9988680/article/details/78160100
今日推荐