建议:函数调用的时候,调用方传给被调用方的参数,如果在调用之后还会被修改,那么调用方应该给被调用方传一个当时的拷贝,深拷贝,否则:
可能被调用方是异步执行的,如果调用函数之后,参数发生了修改,那么被调用方执行的时候,看到的就是被修改之后的数据,这将导致严重、隐蔽、非必现的BUG,而这种BUG是最让人头疼的
可能被调用方会修改传入的参数,这就导致函数执行完毕之后,调用方看到的数据发生了非预期的变化,这同样会导致严重、隐蔽的BUG
深拷贝:这里需要弄清楚深浅拷贝的区别,用“=”号给非基本类型赋值,均是浅拷贝,例如List,以下代码就是浅拷贝:
代码执行完毕之后,list2将包含整数1和2。
代码执行完毕之后,list2将只包含整数1,不包含整数2。 Immutable对象:上述情形如果遇到immutable对象,即不可变对象,其实是不需要深拷贝的(不仅不需要,还应该杜绝拷贝,因为纯属浪费)。但是前提是对象是真正的immutable。反面例子为:
而如果getList()函数不直接返回mList引用,创建一个副本,或者使其不可被改变,则可以达到”严格意义上的“immutable。例如:
上面两种方式各有优劣:前者允许对新获取到的副本进行修改操作而不会抛出异常,但会把底层数组数据创建多份;后者不会创建多份底层数组数据,但是如果对getList()返回的引用进行修改操作,将会抛出异常;见仁见智。 unmodifiable:unmodifiable不等于immutable,所以对于前面提到的建议做法,直接传入unmodifiable是不对的,因为这样只能阻止被调用方修改传入数据后导致调用方出错,并不能阻止调用方修改后导致被调用方出错。unmodifiable并未拷贝底层数组数据,而是实现了另外一个List的实现类,该类的修改操作均抛出异常。 https://github.com/Piasy/notes/blob/master/misc/copy.md |
小黑屋|在路上
( 蜀ICP备15035742号-1 )
GMT+8, 2025-7-9 13:27
Copyright 2015-2025 djqfx