假设如下情景:
A a=new A();
A b=new A();
b=a;
- 那么当a改变时,b的值也会受到影响,即引用赋值,java中虽然没有指针,但引用赋值的本质还是指针,就是说b=a;时,b指向了a的地址,这时b就相当于a了,a在外面乱来,b在不知不觉中也在乱来…emmm大概就是这么个意思。
- 那么我肯定不能让b乱来啊,我希望b还是那个善良单纯可爱的b,就是说希望b能保存a赋值时刻的状态,b就是b,颜色不一样的烟火。所以要用到克隆clone,让一个封装的对象 implements Cloneable,然后重写 Object clone()方法,return super.clone();保持不变就好。因为要在可能跨包调用,所以把默认的protected修饰符改为public,然后在需要用的地方,如b=new A(); b=(A)a.clone();
- 上面说的是浅克隆,那么还有深克隆。那两者的区别是什么呢,当对象A中一个属性也是一个对象如C,那么单纯的浅克隆之后,对于a,b而言,属性C就变成了引用赋值,意味着b=a;当a改变C的值,那么b的C的值也会受影响,那么就需要深克隆了。
- 如何进行深克隆,重写clone。A a=(A)super.clone();先完成对A对象的克隆,A.setC( ( C ) a.getC().clone );完成对C属性的克隆,然后return a;当然C对象也需要实现并重写clone方法,即浅克隆参照上述2所述。
- 那我是怎么遇到这情况的呢?在实现接口的时候,参数需要多内容,但不希望参数过长,不过有的内容有些场景用不到,懒得写重载,那么索性弄个对象来当参数。一来二去,不同地方实现接口,把对象传来传去。。。它就开始乱来了,因为其他场景使用接口时只需要接口参数对象的值,但传进去的参数(那个对象)一直在工作使用,那么问题就来了。
- 补充一点,如果单纯传递对象时,想保存状态,后续也不考虑需要修改值的话,用final接收一下,应该也可以(具体没试过,觉得可行);还有一种办法就是采用序列化反射赋值,用Gson也好,Serializable也罢。