黑马程序员技术交流社区

标题: java对象克隆学习总结,深复制,浅复制 [打印本页]

作者: 29198102shihao    时间: 2013-7-25 11:47
标题: java对象克隆学习总结,深复制,浅复制
对象克隆clone
浅克隆:被复制的的对象,属性值相同,对象引用属性指向原对象(同一对象),方法也相同。
深克隆:被复制的的对象,属性值相同,对象引用属性指向重新复制的新对象,对象及其对象引用属性指向的对象都被复制!方法也相同。
1Object类的protected clone()方法里面有对克隆的要求:??Objec
  1x.clone()!=x;不再是同一对象
  2x.clone() .getClass()=x.getClass() 都是属于一个类
  3x.clone().equals(x);对象相等
2浅clone:1就是实现Cloneable接口(空接口)并2重写Object 的clone方法,并声明为public!为了让其他类可以调用该方法。clone方法第一行调用super.clone(),功能是:识别要克隆哪个对象,为对象分配空间,并完成赋值,返回复制的对象。
例1:
1class Student implements Cloneable{
private int age;private String name; 并封装
public Object clone(){
Object o=super.clone();
return o;}}
2main(){
Student s=new Student(); s.set###
Student s2=(Student)s.clone();}
例2:含有引用变量的对象
1class Teacher implements Cloneable{priavte int age; private String name; 封装}
2class Student implenments Cloneable{priavte int age; private String name; 封装
private Teacher t;也封装了
public Object clone(){
Object o=super.clone();
return o;}}
3main’{
Teacher t=new Teacher();t.set##
Student s=new Student();s.setT(t);
Student s2=(Student)s.clone(); s1 s2 对象的t引用都指向同一对象!}
2深复制
1对上面改进一下就可以实现深复制!
1 让Teacher也重写clone方法
2 Teacher t=new Teacher();t.set##
Student s=new Student();s.setT(t);
Student s2=(Student)s.clone();
s2.setT((Teacher)t.clone()); 对引用变量也克隆再重新赋值
但太麻烦了!!
2用序列化实现!因为序列化本身就自动提供对引用属性的也序列化,让被复制的对象以及其引用属性对象实现Serializable接口,序列化到文件上,然后读出,读出的对象就是复制后的对象!!不用再去重写clone方法
实现:
1class Teacher implements Serializable{priavte int age; private String name; 封装}
2class Student implements Serializable{priavte int age; private String name; 封装
private Teacher t;也封装了
public Object deepCopy(){在类里定义深copy方法,先将对象序列化,再反序列化
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(); 反序列化返回对象!
3 Teacher t=new Teacher();t.set##
Student s=new Student();s.setT(t);
Student s2=(Student)s.deepCopy();

当一个类实现Serializable接口时,eclipse要求定义成员变量:
long serialVersionUID,保证序列化和反序列化后版本兼容:例如:序列化后,原来的类增加了新的属性,反序列化的对象就不兼容了,报错!;
可以让eclipse自动生成:直接点警告自动生成,值是随机的。
但如果序列化对象和反序列化的对象serialVersionUID值相同,原来的类属性增加,反序列化后的对象也会新增属性,值为默认值,如果原来类属性被删,反序列化后的对象忽略该属性,不在序列化question!!!????



InputStream有子类:FilterInputStream类其下面的子类都是包装流:DataInputStream
BufferedInputStream。OutputStream也是一样的对称的!
  1BufferedOutputStream 之前是没写一个字节都要和io设备打一次交道,而现在是把字节先放在buffer里,一旦已满,就一次性写入io,效率更高!
OutputStream os=new FileOutputStream(“123.text”);节点流
  2BufferedOutputStream bs=new BufferedOutputStream(os);对节点流的包装,增加了缓冲功能
bs.write(“asd”.getBytes());bs.close();只需关闭最外层流
也可以强制buffer写入目标:bs.flush();
bs.close();调用时会自动调用bs.flush();
  3


2BufferedWriter BufferedReader 装饰流 最常包装在字符流上面,提供缓冲功能,效率更高!
例如
3标准输入输出节点流 System.out是PrintStream子类,标准输出设备屏幕和System.in是InputStream子类,标准输入设备键盘,都是字节流!!
String s;
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
while(null!=(s=br.readLine())){print(eded);}
键盘输入什么,只要按回车就会显示。

作者: 逆袭的风    时间: 2013-7-26 11:08
先留名,以后再来
作者: sergio    时间: 2013-7-29 23:03
收藏之,很好这边有点欠缺!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2