如何修改Model类属性?实现对象独立/关联修改的示例方案
解决方案
一、修改b时a属性保持不变(独立对象)
当前b = a是引用赋值,两个变量指向内存中同一个对象,所以修改任意一个都会影响另一个。要实现两者独立,需要创建原对象的拷贝,避免共享引用,针对字段多的场景,推荐以下两种高效方式:
1. 实现Cloneable接口快速拷贝
在MyModel中实现Cloneable接口并重写clone方法,无需逐个赋值字段:
package MyPackage.Models; public class MyModel implements Cloneable { private int id; public MyModel() {} public MyModel(int id) { this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override protected Object clone() throws CloneNotSupportedException { // 浅拷贝:若Model包含引用类型字段(如其他对象),需手动拷贝这些字段实现深拷贝 return super.clone(); } }
使用示例:
MyModel a = new MyModel(); a.setId(1); Log.i("nadertag", "a=" + a.getId()); // 通过clone创建独立拷贝,而非直接引用赋值 MyModel b = (MyModel) a.clone(); Log.i("nadertag", "b=" + b.getId()); b.setId(2); Log.i("nadertag", "a=" + a.getId() + "," + "b=" + b.getId());
2. 序列化实现通用深拷贝
如果Model包含多层嵌套的引用类型字段,序列化是最省心的深拷贝方式,自动处理所有字段:
首先让MyModel实现Serializable接口:
package MyPackage.Models; import java.io.Serializable; public class MyModel implements Serializable { private int id; // 构造方法、getter、setter保持不变 }
编写通用拷贝工具方法:
public static <T extends Serializable> T deepCopy(T obj) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(obj); oos.flush(); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (T) ois.readObject(); } catch (Exception e) { e.printStackTrace(); return null; } }
使用示例:
MyModel a = new MyModel(); a.setId(1); Log.i("nadertag", "a=" + a.getId()); MyModel b = deepCopy(a); Log.i("nadertag", "b=" + b.getId()); b.setId(2); Log.i("nadertag", "a=" + a.getId() + "," + "b=" + b.getId());
二、维持修改b时a同步改变的关联状态
当前的b = a已经实现了这个效果,因为两个变量指向同一个对象,修改任意一个都会同步到另一个。如果需要更灵活的关联控制,可参考以下两种方式:
1. 直接引用赋值(最简方案)
保留你当前的写法即可,本质是让两个变量共享同一个对象实例:
MyModel a = new MyModel(); MyModel b = new MyModel(); a.setId(1); Log.i("nadertag", "a=" + a.getId()); b = a; // 引用赋值,共享同一对象 Log.i("nadertag", "b=" + b.getId()); b.setId(2); Log.i("nadertag", "a=" + a.getId() + "," + "b=" + b.getId());
输出结果:
a=1
b=1
a=2,b=2
2. 共享包装类(灵活切换关联)
如果需要后续动态切换b的关联对象(比如从关联a改成关联c),可以用包装类持有目标对象:
public class ModelWrapper { private MyModel target; public ModelWrapper(MyModel target) { this.target = target; } public MyModel getTarget() { return target; } public void setTarget(MyModel target) { this.target = target; } }
使用示例:
MyModel a = new MyModel(); a.setId(1); ModelWrapper wrapper = new ModelWrapper(a); // b通过包装类关联a MyModel b = wrapper.getTarget(); Log.i("nadertag", "b=" + b.getId()); b.setId(2); Log.i("nadertag", "a=" + a.getId() + "," + "b=" + b.getId()); // 后续可切换关联对象 MyModel c = new MyModel(3); wrapper.setTarget(c); b = wrapper.getTarget(); b.setId(4); Log.i("nadertag", "c=" + c.getId() + "," + "b=" + b.getId());
内容的提问来源于stack exchange,提问作者Nader Naderi
相关产品推荐
相关产品推荐

