克隆,就是复制一个对象的副本,而克隆又分浅克隆和深克隆。浅克隆是指克隆得到的对象基本类型的值改变了,而源对象的值不会变。但如果被克隆对象引用类型的值改变了,那么源对象的值同样会改变,因为引用类型在栈内存中存放的是一个引用地址,被克隆对象后也和源对象的引用地址一样,都是指向同样的内存空间的值。所以在克隆时,任何一个对象的值的改变都会令另外的值改变,所以这种情况下要用深克隆。
要注意的是要克隆的对象的泪必须继承cloneable接口,而该接口不提供任何抽象非抽象方法,所以又可以把它看做是克隆的标志性东西。浅克隆的特点是只克隆该对象本体,它的优缺点就是一改皆改;深克隆的特点是新建对象,与源对象互不干扰,而它的优缺点也是互不干扰和麻烦。通常情况下我们使用克隆的时候都只使用浅克隆。
对克隆可以简单的理解为:当克隆一个对象时,把属性的值和方法都一起拷贝的是浅拷贝,而方法的值可以设置不同的是深克隆。深克隆要进行反序例化,先把内容输出到内存,再从内存读取。
代码示例:
package clone;
import
java.io.ByteArrayInputStream;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
java.io.ObjectInputStream;
import
java.io.ObjectOutputStream;
import
java.io.Serializable;
public class BasketballStar
implements Cloneable,Serializable{
private String name;
private int age;
private float height;
private Skill mySkill;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public Skill getMySkill() {
return mySkill;
}
public void setMySkill(Skill mySkill) {
this.mySkill = mySkill;
}
//浅克隆
public Object clone() throws CloneNotSupportedException
{
BasketballStar bs2 = (BasketballStar)super.clone();
bs2.setMySkill((Skill)this.mySkill.clone());
return bs2;
}
public BasketballStar deepClone(){ //深克隆
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
return (BasketballStar)ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally{
try {
bis.close();
ois.close();
bos.close();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
package clone;
import
java.io.Serializable;
public class Skill
implements Cloneable,Serializable{
private int shooting;
private int jumping;
private int strength;
public int getShooting() {
return shooting;
}
public void setShooting(int shooting) {
this.shooting = shooting;
}
public int getJumping() {
return jumping;
}
public void setJumping(int jumping) {
this.jumping = jumping;
}
public int getStrength() {
return strength;
}
public void setStrength(int strength) {
this.strength = strength;
}
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
package clone;
public class MyClone
{
public static void main(String[] args) {
BasketballStar bs1 = new BasketballStar();
bs1.setName("YM");
bs1.setAge(30);
bs1.setHeight( 2.26f);
Skill theSkill = new Skill();
theSkill.setShooting(95);
theSkill.setJumping(50);
theSkill.setStrength(60);
bs1.setMySkill(theSkill);
// try {
// BasketballStar bs2 = (BasketballStar)bs1.clone();
// bs2.setName("YN2");
// bs2.setAge(22);
// bs2.getMySkill().setJumping(90);
// bs2.getMySkill().setStrength(108);
//
// System.out.println(bs1.getMySkill() ==
bs2.getMySkill());
// System.out.println(bs1.getName() + " " +
bs1.getAge());
// System.out.println(bs1.getMySkill().getStrength() + " "
+
// bs1.getMySkill().getJumping());
// } catch (CloneNotSupportedException e) {
// e.printStackTrace();
// }
BasketballStar bs2 = bs1.deepClone();
System.out.println(bs1.getMySkill() ==
bs2.getMySkill());
System.out.println(bs2.getName() + " " +
bs2.getAge());
System.out.println(bs2.getMySkill().getStrength() + " "
+ bs2.getMySkill().getJumping());
}
}