我有深层嵌套结构,“remove(<Something>)
”,“contains(<Something>)
”等方法依赖于对原始引用的访问以便删除它等等(参考文件的副本赢了)不行。。
人们如何最好地解决这个问题,以便他们仍然可以在不同的任意方法和构造函数等中方便地添加,删除,测试他们想要的对象,而不会增加任何不必要的复杂性或任何不必要的性能损失? / p>
答案 0 :(得分:3)
remove
和contains
等方法可以正常传递值。原因是即使复制了引用,它们的副本也具有相同的原始值。只需查看Collections API即可。如果您执行类似(伪代码)
List list = new List();
list.add(object1) // assume you have an object1 reference
然后你做
myRemove(list, object1);
list
和object 1
都按值传递,因此在myRemove
方法中,它们是原始引用的副本。如果在myRemove
中你做了
list.remove(object1);
该对象仍然从列表中删除没问题。此外,由于两个作用域中的list
和object1
引用指向相同的基础对象,因此调用作用域中的列表引用引用已删除对象的列表。
您需要通过引用语义进行传递的唯一时间是您是否要修改方法中的引用并将修改应用于调用该方法的范围。
所以,如果你想做
List myList = new List();
changeList(myList);
并且changeList
更改myList指向调用范围的位置,如果没有一些技巧,它将无法工作。诡计被称为double indirection。基本上,您创建一个对象,该对象具有您希望能够通过引用语义访问的实例,并且您可以传递容器对象。
所以
class MyContainer {
List list
}
现在您可以将MyContainer
的实例传递给方法,并更改列表值,并在调用范围内更改list
点。请注意,您在这里没有做任何特别的事情,所有内容仍然按值传递。
答案 1 :(得分:0)
人们如何最好地解决这个问题......
使用成员字段(用于处理引用,而不是副本)以及使用继承和接口(用于处理嵌套结构)。