Java对象深复制与浅复制实例详解
程序员文章站
2023-12-22 09:53:40
java对象深复制与浅复制实例详解
我们在遇到一些业务场景的时候经常需要对对象进行复制,对于对象的复制一般有两种方式,深复制和浅复制
浅复制:对象的复制仅是...
java对象深复制与浅复制实例详解
我们在遇到一些业务场景的时候经常需要对对象进行复制,对于对象的复制一般有两种方式,深复制和浅复制
浅复制:对象的复制仅是对象本身,对象引用的其它对方并不会复制。
深复制:对象的复制包含对象引用的对象。
java所有对象的基类提供了clone方法,但是这个方法是protected native修饰,因此只暴露给之类去重写,外部是无法直接调用的。
我们现在来测试两种复制,首选是浅复制,浅复制要实现cloneable接口。
// 课程对象 class class { private string name; public string getname() { return name; } public void setname(string name) { this.name = name; } } // 学生对象 class user implements cloneable { private string name; private long id; // 课程引用 private class c; public class getc() { return c; } public void setc(class c) { this.c = c; } public string getname() { return name; } public void setname(string name) { this.name = name; } public long getid() { return id; } public void setid(long id) { this.id = id; } @override protected object clone() throws clonenotsupportedexception { return super.clone(); } @override public int hashcode() { return super.hashcode(); } @override public boolean equals(object obj) { if (obj instanceof user) { user user = (user) obj; if (this.id == user.getid() && this.getname() == user.getname()) { return true; } if (user.getid().equals(this.id) && user.getname().equals(this.name)) { return true; } return false; } else return false; } }
我们来测试:
user user1 = new user(); user user2 = user1; user user3 = (user) user1.clone(); system.out.println(user1 == user2); system.out.println(user3 == user1); system.out.println(user3.equals(user1)); system.out.println(user3.getname() == user3.getname());// true,浅复制 class c = new class(); c.setname("语文"); user1.setc(c); // 测试复制深度 user user4 = (user) user1.clone(); system.out.println(user4.getc() == user1.getc()); // true,说明引用的对象依然是同一个对象
对象的复制并没复制引用所指向的对象class,复制出来的引用指向的同一个地址。
深复制采用序列化与反序列的方式去获取,也有种说法类似于腌菜,用流的方式腌制进去又取出来,实现深度复制。
class car implements serializable { /** * */ private static final long serialversionuid = 42342l; private string name; public string getname() { return name; } public void setname(string name) { this.name = name; } } // 深复制 class people implements serializable{ /** * */ private static final long serialversionuid = 543535212412l; private car car; public car getcar() { return car; } public void setcar(car car) { this.car = car; } public people deepclone() throws ioexception, classnotfoundexception { // 腌制 bytearrayoutputstream out = new bytearrayoutputstream(); objectoutputstream oos = new objectoutputstream(out); oos.writeobject(this); // 取出 bytearrayinputstream input = new bytearrayinputstream(out.tobytearray()); objectinputstream ois = new objectinputstream(input); return (people) ois.readobject(); } }
测试深复制:
// 深复制 car car = new car(); car.setname("benz"); people p = new people(); p.setcar(car); try { people p2 = p.deepclone(); system.out.println(p2.getcar() == p.getcar()); // false,说明引用的对象也进行了复制 } catch (classnotfoundexception | ioexception e) { e.printstacktrace(); }
例外提及一下生成对象的五种办法:
1.new
2.class类的newinstance
3.constructor类newinstance
4.clone方式
5.反序列化的方式
其中2与3即是反射的方式。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!