概念
⑴浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。
换言之,浅复制仅仅复制所考虑的对象,而不
复制它所引用的对象。
⑵深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用
其他对象的变量将指向被复制过的新对象,而不再是原
有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
浅克隆实现:覆写父类的clone
深克隆实现:
1.覆写父类的clone,并增加所有引用的clone
2.序列化
浅克隆
class Person implements Cloneable {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Object clone() {
Person o = null;
try {
o = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
@Override
public String toString() {
return "名字:" + this.name + "年龄:" + this.age;
}
}
public class SClass {
public static void main(String[] args) {
Person person = new Person("senssic", 20);
System.out.println(person.toString());// Person的初始值
Person p = (Person) person.clone();// 浅克隆Person
p.name = "qiyu";// 修改克隆对象的值
System.out.println(person.toString());// person对象克隆后的值,修改对象克隆后的值不会对原对象初始值产生影响
}
}
运行结果:
名字:senssic年龄:20
名字:senssic年龄:20
package senssic.demo;
class Pro {
String addre;
int phon;
public Pro(String addre, int phon) {
this.addre = addre;
this.phon = phon;
}
@Override
public String toString() {
return "地址:" + this.addre + "电话:" + this.phon;
}
}
class Person implements Cloneable {
String name;
int age;
Pro pro;
public Person(String name, int age, Pro pro) {
this.name = name;
this.age = age;
this.pro = pro;
}
@Override
public Object clone() {
Person o = null;
try {
o = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
@Override
public String toString() {
return "名字:" + this.name + "年龄:" + this.age + "--->"
+ this.pro.toString();
}
}
public class SClass {
public static void main(String[] args) {
Pro pro = new Pro("安徽", 123);
Person person = new Person("senssic", 20, pro);
System.out.println(person.toString());// Person的初始值
Person p = (Person) person.clone();// 浅克隆Person
p.name = "qiyu";// 修改克隆后对象的值
System.out.println(person.toString());// 修改对象克隆后的值不会对原对象初始值产生影响
p.pro.addre = "池州";// 修改克隆后对象引用的值
System.out.println(person.toString());// 修改对象克隆后引用的值会对原对象初始值产生影响
}
}
运行结果:
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:池州电话:123
深克隆
1.覆写父类的clone,并增加所有引用的clone
package senssic.demo;
class Pro implements Cloneable {
String addre;
int phon;
public Pro(String addre, int phon) {
this.addre = addre;
this.phon = phon;
}
@Override
public String toString() {
return "地址:" + this.addre + "电话:" + this.phon;
}
@Override
public Object clone() {
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return object;
}
}
class Person implements Cloneable {
String name;
int age;
Pro pro;
public Person(String name, int age, Pro pro) {
this.name = name;
this.age = age;
this.pro = pro;
}
@Override
public Object clone() {
Person o = null;
try {
o = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
o.pro = (Pro) pro.clone();
return o;
}
@Override
public String toString() {
return "名字:" + this.name + "年龄:" + this.age + "--->"
+ this.pro.toString();
}
}
public class SClass {
public static void main(String[] args) {
Pro pro = new Pro("安徽", 123);
Person person = new Person("senssic", 20, pro);
System.out.println(person.toString());// Person的初始值
Person p = (Person) person.clone();// 浅克隆Person
p.name = "qiyu";// 修改克隆后对象的值
System.out.println(person.toString());// 修改对象克隆后的值不会对原对象初始值产生影响
p.pro.addre = "池州";// 修改克隆后对象引用的值
System.out.println(person.toString());// 修改对象克隆后引用的值也不会对原对象初始值产生影响
}
}
运行结果:
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123
2.利用序列化进行深克隆
必须实现序列化接口
package senssic.demo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.Serializable;
class Pro implements Serializable {// 需要实现序列化接口
String addre;
int phon;
public Pro(String addre, int phon) {
this.addre = addre;
this.phon = phon;
}
@Override
public String toString() {
return "地址:" + this.addre + "电话:" + this.phon;
}
}
class Person implements Serializable {
String name;
int age;
Pro pro;
public Person(String name, int age, Pro pro) {
this.name = name;
this.age = age;
this.pro = pro;
}
public Object deepClone() {// 将对象写到流里
Object object = null;
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);// 从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
object = new ObjectInputStream(bi).readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (OptionalDataException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return object;
}
@Override
public String toString() {
return "名字:" + this.name + "年龄:" + this.age + "--->"
+ this.pro.toString();
}
}
public class SClass {
public static void main(String[] args) {
Pro pro = new Pro("安徽", 123);
Person person = new Person("senssic", 20, pro);
System.out.println(person.toString());// Person的初始值
Person p = (Person) person.deepClone();// 浅克隆Person
p.name = "qiyu";// 修改克隆后对象的值
System.out.println(person.toString());// 修改对象克隆后的值不会对原对象初始值产生影响
p.pro.addre = "池州";// 修改克隆后对象引用的值
System.out.println(person.toString());// 修改对象克隆后引用的值也不会对原对象初始值产生影响
}
}
运行结果:
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123
名字:senssic年龄:20--->地址:安徽电话:123