java对象的浅克隆和深克隆
2021-06-24 03:03
标签:exce 序列 不能 stat name 子类 import inpu hid 在Object基类中,有一个方法叫clone,产生一个前期对象的克隆,克隆对象是原对象的拷贝,由于引用类型的存在,有深克隆和浅克隆之分,若克隆对象中存在引用类型的属性,深克隆会将此属性完全拷贝一份,而浅克隆仅仅是拷贝一份此属性的引用。首先看一下容易犯的几个小问题 浅克隆就是引用类型的属性无法完全复制,类User中包含成绩属性Mark,Mark是由Chinese和math等等组成的,浅克隆失败的例子 输出结果为: 原user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=99}} 很清楚的看到user的mark更改后,被克隆的user也修改了。而要想不被影响,就需要深克隆了。 既然引用类型无法被完全克隆,那将引用类型也实现Cloneable接口重写clone方法,在User类中的clone方法调用属性的克隆方法,也就是方法的嵌套调用 输出结果为: 原user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=99}} 上一种方法已经足够满足我们的需要,但是如果类之间的关系很多,或者是有的属性是数组呢,数组可无法实现Cloneable接口(我们可以在clone方法中手动复制数组),但是每次都得手写clone方法,很麻烦,而序列化方式只需要给每个类都实现一个Serializable接口,也是标记接口,最后同序列化和反序列化操作达到克隆的目的(包括数组的复制)。序列化和反序列化的知识请参照下一篇 输出结果: 原user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=99}} 带数组属性的克隆: java对象的浅克隆和深克隆 标签:exce 序列 不能 stat name 子类 import inpu hid 原文地址:https://www.cnblogs.com/gollong/p/9668699.html引言:
protected native Object clone() throws CloneNotSupportedException;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
浅克隆:
class Mark{
private int chinese;
private int math;
public Mark(int chinese, int math) {
this.chinese = chinese;
this.math = math;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public void setMath(int math) {
this.math = math;
}
@Override
public String toString() {
return "Mark{" +
"chinese=" + chinese +
", math=" + math +
‘}‘;
}
}
public class User implements Cloneable{
private String name;
private int age;
private Mark mark;
public User(String name, int age,Mark mark) {
this.name = name;
this.age = age;
this.mark = mark;
}
@Override
public String toString() {
return "User{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", mark=" + mark +
‘}‘;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
Mark mark = new Mark(100,99);
User user = new User("user",22,mark);
User userClone = (User) user.clone();
System.out.println("原user:"+user);
System.out.println("克隆的user:"+userClone);
//修改引用类型的mark属性
user.mark.setMath(60);
System.out.println("修改后的原user:"+user);
System.out.println("修改后的克隆user:"+userClone);
}
}
克隆的user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=99}}
修改后的原user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=60}}
修改后的克隆user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=60}}深克隆:
方式一:clone函数的嵌套调用
class Mark implements Cloneable{
private int chinese;
private int math;
public Mark(int chinese, int math) {
this.chinese = chinese;
this.math = math;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public void setMath(int math) {
this.math = math;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Mark{" +
"chinese=" + chinese +
", math=" + math +
‘}‘;
}
}
public class User implements Cloneable{
private String name;
private int age;
private Mark mark;
public User(String name, int age,Mark mark) {
this.name = name;
this.age = age;
this.mark = mark;
}
@Override
public String toString() {
return "User{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", mark=" + mark +
‘}‘;
}
@Override
protected Object clone() throws CloneNotSupportedException {
User user = (User) super.clone();
user.mark = (Mark) this.mark.clone();
return user;
}
public static void main(String[] args) throws CloneNotSupportedException {
Mark mark = new Mark(100,99);
User user = new User("user",22,mark);
User userClone = (User) user.clone();
System.out.println("原user:"+user);
System.out.println("克隆的user:"+userClone);
//修改引用类型的mark属性
user.mark.setMath(60);
System.out.println("修改后的原user:"+user);
System.out.println("修改后的克隆user:"+userClone);
}
}
克隆的user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=99}}
修改后的原user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=60}}
修改后的克隆user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=99}} 方式二:序列化
import java.io.*;
class Mark implements Serializable {
private int chinese;
private int math;
public Mark(int chinese, int math) {
this.chinese = chinese;
this.math = math;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public void setMath(int math) {
this.math = math;
}
@Override
public String toString() {
return "Mark{" +
"chinese=" + chinese +
", math=" + math +
‘}‘;
}
}
public class User implements Serializable{
private String name;
private int age;
private Mark mark;
public User(String name, int age,Mark mark) {
this.name = name;
this.age = age;
this.mark = mark;
}
@Override
public String toString() {
return "User{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", mark=" + mark +
‘}‘;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Mark mark = new Mark(100,99);
User user = new User("user",22,mark);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(user);//序列化
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
User userClone = (User) oi.readObject();//反序列化
System.out.println("原user:"+user);
System.out.println("克隆的user:"+userClone);
user.mark.setMath(59);
System.out.println("修改后的原user:"+user);
System.out.println("修改后的克隆user:"+userClone);
}
}
克隆的user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=99}}
修改后的原user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=60}}
修改后的克隆user:User{name=‘user‘, age=22, mark=Mark{chinese=100, math=99}}import java.io.*;
import java.util.Arrays;
public class User implements Serializable{
private String name;
private int age;
private int[] arr;
public User(String name, int age, int[] arr) {
this.name = name;
this.age = age;
this.arr = arr;
}
@Override
public String toString() {
return "User{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
", arr=" + Arrays.toString(arr) +
‘}‘;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
int[] arr = {1,2,3,4,5,6};
User user = new User("user",22,arr);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(user);//序列化
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
User userClone = (User) oi.readObject();//反序列化
System.out.println("原user:"+user);
System.out.println("克隆的user:"+userClone);
user.arr[1] = 9;
System.out.println("修改后的原user:"+user);
System.out.println("修改后的克隆user:"+userClone);
}
}
上一篇:Java中Int转byte分析
下一篇:拓扑排序复习——Chemist