对象实现copy有多中方式,最土的方法就是直接new,然后塞值,不过这种方法是真的low,下面着重说说Object类中的clone() 和 序列化反序列化copy
Object 中 clone的方法
1.Object中clone 方法是protected,虽然所有类都继承自object 但是在不同包下调用还是不被允许的,因此要重写clone方法。
2.调用clone方法clone对象时要求对象实现Cloneable接口,否则会抛出 CloneNotSupportedException
/** @return a clone of this instance.
* @throws CloneNotSupportedException if the object's class does not
* support the {@code Cloneable} interface. Subclasses
* that override the {@code clone} method can also
* throw this exception to indicate that an instance cannot
* be cloned.
* @see java.lang.Cloneable
*/
protected native Object clone() throws CloneNotSupportedException;
clone 方法可以实现对象的浅copy ,什么是浅copy 举个例子
人 有 头 和 名字 两个属性 , 头 又有 头发 属性 ,现在使用clone方法 克隆一个人,则clone出来的人和原有的人是两个对象,但是发现两个人的头在内存中只有一个,也就是说,clone出来的人使用了原有人的头对象。如果改了其中一个对象头对象的属性,另一个也会跟着变。
序列化和反序列化,将对象读到内存中,在从内存中读取出来
需要对象实现 Serializable 接口
直接上代码了,自己跑即可:
import lombok.extern.slf4j.Slf4j; import java.io.*; /**
* @ClassName CommonUtils
* @Description <工具类></>
* @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
* @Date 2018/12/4 11:39
* @Version 1.0
*/
@Slf4j
public class CommonUtils { /**
* @return T
* @Description <深度克隆对象,对象需要序列化>
* @Author Zhaiyt
* @Date 14:11 2018/12/4
* @Param [obj]
**/
public static <T extends Serializable> T clone(T obj) {
try {
//将对象读取到内存中
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
//从内存中读取
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (T) objectInputStream.readObject();
} catch (IOException e) {
log.error("clone Object IOException");
} catch (ClassNotFoundException e) {
log.error("clone Object ClassNotFoundException");
}
return null;
} public static void main(String[] args) {
Person p = new Person();
p.setName("zhangsan");
p.setSix("男");
Head h = new Head();
h.setHair("black");
p.setHead(h);
Person cloneP = clone(p);
System.out.println("深copy对象的属性 p.head 和 cloneP.head 是否相等");
System.out.println(p.getHead().equals(cloneP.getHead())); //浅copy
Person clone;
try {
clone = (Person) p.clone();
System.out.println("浅copy对象的属性 p.head 和 clone.head");
System.out.println(p.getHead().equals(clone.getHead()));
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
} /**
* @ClassName <Person>
* @Description <人对象>
* @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
* @Date 2018/12/4 16:12
* @Version 1.0
*/
class Person implements Serializable, Cloneable {
private String name; private String six; private Head head; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSix() {
return six;
} public void setSix(String six) {
this.six = six;
} public Head getHead() {
return head;
} public void setHead(Head head) {
this.head = head;
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
} @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", six='" + six + '\'' +
", head=" + head +
'}';
}
} /**
* @ClassName <Head>
* @Description <人的属性>
* @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
* @Date 2018/12/4 16:11
* @Version 1.0
*/
class Head implements Serializable {
private String hair; public String getHair() {
return hair;
} public void setHair(String hair) {
this.hair = hair;
} @Override
public String toString() {
return "Head{" +
"hair='" + hair + '\'' +
'}';
}
}
序列化和反序列化后出来的对象发现属性对象不再是同一个对象了。