本文实例讲述了java实现 克隆 的三种方式。分享给大家供大家参考,具体如下:
1、浅复制(浅克隆)这种浅复制,其实也就是把被复制的这个对象的一些变量值拿过来了。最后生成student2还是一个新的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public class clonetest1 { public static void main(string[] args) throws exception { student1 student = new student1(); student.setage( 24 ); student.setname( "niesong" ); student1 student2 = (student1)student.clone(); //这个是调用下面的那个方法,然后把这个这个对象clone到student system.out.println( "age:" + student2.getage() + " " + "name:" + student2.getname()); system.out.println( "---------------------" ); student2.setage( 23 ); //克隆后得到的是一个新的对象,所以重新写的是student2这个对象的值 system.out.println(student.getage()); system.out.println(student2.getage()); } } //克隆的对象必须实现cloneable这个接口,而且需要重写clone方法 class student1 implements cloneable { private int age; //定义为private说明这个成员变量只能被被当前类中访问,如果外部需要获得,那么就只能通过getage方法进行获取 private string name; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } @override public object clone() throws clonenotsupportedexception { object object = super .clone(); return object; } } |
运行结果:
2、深复制(情况1使用的是在克隆的时候手动进行深克隆)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
public class clonetest2 { public static void main(string[] args) throws exception { teacher teacher = new teacher(); teacher.setage( 40 ); teacher.setname( "teacher zhang" ); student2 student2 = new student2(); student2.setage( 14 ); student2.setname( "lisi" ); student2.setteacher(teacher); student2 student3 = (student2)student2.clone(); //这里是深复制,所以这时候student2中的teacher就是teacher这个对象的一个复制,就和student3是student2的一个复制 //所以下面teacher.setname只是对他原来的这个对象更改,但是复制的那个并没有更改 system.out.println(student3.getage()); system.out.println(student3.getname()); system.out.println(student3.getteacher().getage()); teacher.setname( "teacher niesong" ); //不会又任何影响 system.out.println(student3.getteacher().getname()); } } class student2 implements cloneable { private int age; private string name; private teacher teacher; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } public teacher getteacher() { return teacher; } public void setteacher(teacher teacher) { this .teacher = teacher; } @override public object clone() throws clonenotsupportedexception { //这一步返回的这个student2还只是一个浅克隆, student2 student2 = (student2) super .clone(); //然后克隆的过程中获得这个克隆的student2,然后调用这个getteacher这个方方法得到这个teacher对象。然后实现克隆。在设置到这个student2中的teacher。 //这样实现了双层克隆使得那个teacher对象也得到了复制。 student2.setteacher((teacher)student2.getteacher().clone()); //双层克隆使得那个teacher对象也得到了复制 return student2; } } class teacher implements cloneable { private int age; private string name; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } @override public object clone() throws clonenotsupportedexception { return super .clone(); } } |
运行结果:
3、利用serializable实现深复制(这个是利用serializable,利用序列化的方式来实现深复制(深克隆),在其中利用了io流的方式将这个对象写到io流里面,然后在从io流里面读取,这样就实现了一个复制,然后实现序列化的这个会将引用的那个对象也一并进行深复制,这样就实现了这个机制,同时在io里面读取数据的时候还使用了装饰者模式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
import java.io.bytearrayinputstream; import java.io.bytearrayoutputstream; import java.io.objectinputstream; import java.io.objectoutputstream; import java.io.serializable; public class clonetest3 { public static void main(string[] args) throws exception { teacher3 teacher3 = new teacher3(); teacher3.setage( 23 ); teacher3.setname( "niesong" ); student3 student3 = new student3(); student3.setage( 50 ); student3.setname( "wutao" ); student3.setteacher3(teacher3); student3 ss = (student3)student3.deepcopt(); system.out.println(ss.getage()); system.out.println(ss.getname()); system.out.println( "---------------------" ); system.out.println(ss.getteacher3().getage()); system.out.println(ss.getteacher3().getname()); system.out.println( "-----------------------" ); ss.getteacher3().setage( 7777 ); ss.getteacher3().setname( "hhhhh" ); system.out.println(teacher3.getage()); system.out.println(teacher3.getname()); //虽然上面的已经改了,但是改的是那个复制对象后的那个里面的,然后那个原来的那个里面的并没有改,下面验证::: system.out.println( "-----------------" ); system.out.println(ss.getteacher3().getage()); system.out.println(ss.getteacher3().getname()); } } class teacher3 implements serializable { // 上面的那个警告可以直接消除,除了使用在设置中不显示这个警告,还可以使用下面的这两条语句中的任何一条语句 // 这个serialversionuid为了让该类别serializable向后兼容 // private static final long serialversionuid = 1l; // private static final long serialversionuid = 8940196742313994740l; private int age; private string name; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } } class student3 implements serializable { private static final long serialversionuid = 1l; private int age; private string name; private teacher3 teacher3; public int getage() { return age; } public void setage( int age) { this .age = age; } public string getname() { return name; } public void setname(string name) { this .name = name; } public teacher3 getteacher3() { return teacher3; } public void setteacher3(teacher3 teacher3) { this .teacher3 = teacher3; } //使得序列化student3的时候也会将teacher序列化 public object deepcopt() throws exception { bytearrayoutputstream bos = new bytearrayoutputstream(); objectoutputstream oos = new objectoutputstream(bos); oos.writeobject( this ); //将当前这个对象写到一个输出流当中,,因为这个对象的类实现了serializable这个接口,所以在这个类中 //有一个引用,这个引用如果实现了序列化,那么这个也会写到这个输出流当中 bytearrayinputstream bis = new bytearrayinputstream(bos.tobytearray()); objectinputstream ois = new objectinputstream(bis); return ois.readobject(); //这个就是将流中的东西读出类,读到一个对象流当中,这样就可以返回这两个对象的东西,实现深克隆 } } |
运行结果:
希望本文所述对大家java程序设计有所帮助。
原文链接:https://blog.csdn.net/qq_28081081/article/details/80455150
查看更多关于Java实现克隆的三种方式实例总结的详细内容...