在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在这种情况下常常使用clone。当然你完全可以new一个新的,让后再进行赋值。但应用clone会有如下的好处:
1、实现clone方法比较简单、方便。
2、Object类的clone()一个native方法,native方法的效率一般来说都是远高于java中的非native方法,因此clone方法是高效的。
注意;通过序列化的方式也可以实现clone。如果一个对象包含复杂类型的变量时,可用序列化或深度clone来实现对象的clone。
浅度复制和深度复制
在java中,对于基本类型的数据可采用浅度复制的方式进行对象的复制,其中做法就是直接继承Cloneable接口,调用Object类的clone()方法就可以了。而对于非基本类型的数据,复制方法只能采用深度复制或序列化的方式进行复制。 典型的实例:- /**
- *
- * @功能 羊对象类
- * @创建人 gao_jie
- * @创建日期 Jun 25, 2009
- * @版本 1.0
- *
- */
- public class Sheep implements Cloneable {
- private String name;//名字
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- /* (non-Javadoc)
- * @see java.lang.Object#clone()
- */
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- public class Sheepfold implements Cloneable {
- public Sheep sheep;//羊对象
- public String name;//羊圈名字
- public int number;//数量
- public Sheepfold() {
- this.sheep = new Sheep();
- }
- /* (non-Javadoc)
- * @see java.lang.Object#clone()
- */
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- public class Test {
- public static void main(String[] args) {
- // 声明一个小羊圈对象
- Sheepfold smallFold = new Sheepfold();
- smallFold.name = "小羊圈";
- smallFold.number = 10;
- smallFold.sheep.setName("小羊");
- // 复制羊圈
- Sheepfold bigFold = null;
- try {
- bigFold = (Sheepfold) smallFold.clone();
- } catch (CloneNotSupportedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- bigFold.name="大羊圈";
- bigFold.number=100;
- bigFold.sheep.setName("大羊");
- System.out.println("小羊圈输出信息如下:");
- System.out.println("smallFold.name="+smallFold.name);
- System.out.println("smallFold.number="+smallFold.number);
- System.out.println("smallFold.sheep="+smallFold.sheep.getName());
- System.out.println("大羊圈输出信息如下:");
- System.out.println("bigFold.name="+bigFold.name);
- System.out.println("bigFold.number="+bigFold.number);
- System.out.println("bigFold.sheep="+bigFold.sheep.getName());
- }
- }
- 测试结果:
- 小羊圈输出信息如下:
- smallFold.name=小羊圈
- smallFold.number=10
- smallFold.sheep=大羊
- 大羊圈输出信息如下:
- bigFold.name=大羊圈
- bigFold.number=100
- bigFold.sheep=大羊
- 把上面的例子改成深度clone很简单,只需将Sheepfold的clone()方法改为如下即可:
- public Object clone() throws CloneNotSupportedException {
- Sheepfold fold = (Sheepfold)super.clone();
- sheep = (Sheep)fold.sheep.clone();
- return fold;
- }
- /**
- *
- * @功能 羊对象类
- * @创建人 gao_jie
- * @创建日期 Jun 25, 2009
- * @版本 1.0
- *
- */
- public class Sheep implements Serializable{
- private String name;//名字
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- public class Sheepfold implements Cloneable, Serializable {
- public Sheep sheep;// 羊对象
- public String name;// 羊圈名字
- public int number;// 数量
- public Sheepfold() {
- this.sheep = new Sheep();
- }
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#clone()
- */
- public Object clone() throws CloneNotSupportedException {
- try {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(this);
- // 将流序列化
- ByteArrayInputStream bis = new ByteArrayInputStream(bos
- .toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bis);
- return ois.readObject();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
- 测试类
- public class Test {
- public static void main(String[] args) {
- // 声明一个小羊圈对象
- Sheepfold smallFold = new Sheepfold();
- smallFold.name = "小羊圈";
- smallFold.number = 10;
- smallFold.sheep.setName("小羊");
- // 复制羊圈
- Sheepfold bigFold = null;
- try {
- bigFold = (Sheepfold) smallFold.clone();
- } catch (CloneNotSupportedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- bigFold.name="大羊圈";
- bigFold.number=100;
- bigFold.sheep.setName("大羊");
- System.out.println("小羊圈输出信息如下:");
- System.out.println("smallFold.name="+smallFold.name);
- System.out.println("smallFold.number="+smallFold.number);
- System.out.println("smallFold.sheep="+smallFold.sheep.getName());
- System.out.println("大羊圈输出信息如下:");
- System.out.println("bigFold.name="+bigFold.name);
- System.out.println("bigFold.number="+bigFold.number);
- System.out.println("bigFold.sheep="+bigFold.sheep.getName());
- }
- }
- 测试结果:
- 小羊圈输出信息如下:
- smallFold.name=小羊圈
- smallFold.number=10
- smallFold.sheep=小羊
- 大羊圈输出信息如下:
- bigFold.name=大羊圈
- bigFold.number=100
- bigFold.sheep=大羊
在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在这种情况下常常使用clone。当然你完全可以new一个新的,让后再进行赋值。但应用clone会有如下的好处:
1、实现clone方法比较简单、方便。
2、Object类的clone()一个native方法,native方法的效率一般来说都是远高于java中的非native方法,因此clone方法是高效的。
注意;通过序列化的方式也可以实现clone。如果一个对象包含复杂类型的变量时,可用序列化或深度clone来实现对象的clone。
浅度复制和深度复制
在java中,对于基本类型的数据可采用浅度复制的方式进行对象的复制,其中做法就是直接继承Cloneable接口,调用Object类的clone()方法就可以了。而对于非基本类型的数据,复制方法只能采用深度复制或序列化的方式进行复制。 典型的实例:- /**
- *
- * @功能 羊对象类
- * @创建人 gao_jie
- * @创建日期 Jun 25, 2009
- * @版本 1.0
- *
- */
- public class Sheep implements Cloneable {
- private String name;//名字
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- /* (non-Javadoc)
- * @see java.lang.Object#clone()
- */
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- public class Sheepfold implements Cloneable {
- public Sheep sheep;//羊对象
- public String name;//羊圈名字
- public int number;//数量
- public Sheepfold() {
- this.sheep = new Sheep();
- }
- /* (non-Javadoc)
- * @see java.lang.Object#clone()
- */
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- public class Test {
- public static void main(String[] args) {
- // 声明一个小羊圈对象
- Sheepfold smallFold = new Sheepfold();
- smallFold.name = "小羊圈";
- smallFold.number = 10;
- smallFold.sheep.setName("小羊");
- // 复制羊圈
- Sheepfold bigFold = null;
- try {
- bigFold = (Sheepfold) smallFold.clone();
- } catch (CloneNotSupportedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- bigFold.name="大羊圈";
- bigFold.number=100;
- bigFold.sheep.setName("大羊");
- System.out.println("小羊圈输出信息如下:");
- System.out.println("smallFold.name="+smallFold.name);
- System.out.println("smallFold.number="+smallFold.number);
- System.out.println("smallFold.sheep="+smallFold.sheep.getName());
- System.out.println("大羊圈输出信息如下:");
- System.out.println("bigFold.name="+bigFold.name);
- System.out.println("bigFold.number="+bigFold.number);
- System.out.println("bigFold.sheep="+bigFold.sheep.getName());
- }
- }
- 测试结果:
- 小羊圈输出信息如下:
- smallFold.name=小羊圈
- smallFold.number=10
- smallFold.sheep=大羊
- 大羊圈输出信息如下:
- bigFold.name=大羊圈
- bigFold.number=100
- bigFold.sheep=大羊
- 把上面的例子改成深度clone很简单,只需将Sheepfold的clone()方法改为如下即可:
- public Object clone() throws CloneNotSupportedException {
- Sheepfold fold = (Sheepfold)super.clone();
- sheep = (Sheep)fold.sheep.clone();
- return fold;
- }
- /**
- *
- * @功能 羊对象类
- * @创建人 gao_jie
- * @创建日期 Jun 25, 2009
- * @版本 1.0
- *
- */
- public class Sheep implements Serializable{
- private String name;//名字
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- public class Sheepfold implements Cloneable, Serializable {
- public Sheep sheep;// 羊对象
- public String name;// 羊圈名字
- public int number;// 数量
- public Sheepfold() {
- this.sheep = new Sheep();
- }
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#clone()
- */
- public Object clone() throws CloneNotSupportedException {
- try {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(this);
- // 将流序列化
- ByteArrayInputStream bis = new ByteArrayInputStream(bos
- .toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bis);
- return ois.readObject();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
- 测试类
- public class Test {
- public static void main(String[] args) {
- // 声明一个小羊圈对象
- Sheepfold smallFold = new Sheepfold();
- smallFold.name = "小羊圈";
- smallFold.number = 10;
- smallFold.sheep.setName("小羊");
- // 复制羊圈
- Sheepfold bigFold = null;
- try {
- bigFold = (Sheepfold) smallFold.clone();
- } catch (CloneNotSupportedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- bigFold.name="大羊圈";
- bigFold.number=100;
- bigFold.sheep.setName("大羊");
- System.out.println("小羊圈输出信息如下:");
- System.out.println("smallFold.name="+smallFold.name);
- System.out.println("smallFold.number="+smallFold.number);
- System.out.println("smallFold.sheep="+smallFold.sheep.getName());
- System.out.println("大羊圈输出信息如下:");
- System.out.println("bigFold.name="+bigFold.name);
- System.out.println("bigFold.number="+bigFold.number);
- System.out.println("bigFold.sheep="+bigFold.sheep.getName());
- }
- }
- 测试结果:
- 小羊圈输出信息如下:
- smallFold.name=小羊圈
- smallFold.number=10
- smallFold.sheep=小羊
- 大羊圈输出信息如下:
- bigFold.name=大羊圈
- bigFold.number=100
- bigFold.sheep=大羊