返回对象引用的最佳实践

时间:2010-07-11 21:15:40

标签: java pass-by-reference

请考虑以下代码段:

class MyClass{
    private List myList;
    //...
    public List getList(){
        return myList;
    }
}

当Java按值传递对象引用时,我的理解是任何调用getList()的对象都将获得对myList的引用,允许它修改myList,尽管它是private }。这是对的吗?

而且,如果它是正确的,我应该使用

return new LinkedList(myList);

创建副本并传回对副本的引用,而不是原始副本,以防止未经授权访问myList引用的列表?

5 个答案:

答案 0 :(得分:9)

我这样做。更好的是,有时我使用Collections API返回一个不可修改的副本。

如果您不这样做,您的参考不是私密的。任何有参考的人都可以改变您的私人状态。对于任何可变引用(例如,日期)也是如此。

答案 1 :(得分:2)

这取决于你想要什么。

您是否希望公开列表并进行编辑以便人们可以编辑它?

或者您想让人们看一下,但不能修改它吗?

在这种情况下没有正确或错误的方式。这取决于您的设计需求。

答案 2 :(得分:1)

在某些情况下,人们可能希望将“原始”列表返回给调用者。但总的来说,我认为这是一个不好的做法,因为它打破了封装,因此反对OO。 如果您必须返回“原始”列表而不是副本,那么应该向MyClass的用户明确说明。

答案 3 :(得分:1)

我认为将字段设为私有并提供访问器的模式仅用于数据封装。如果你想要真正私密的东西,不要给它访问方法!然后,您可以编写其他方法来返回私有数据的不可变版本或其副本。

答案 4 :(得分:0)

是的,它有一个名字......“防御性副本”。还建议在接收端进行复制。如Tom has noted,如果集合是不可变的,程序的行为更容易预测。所以除非你有充分的理由,否则你应该使用一个不可变的集合。

Google Guava成为Java标准库的一部分时(我完全认为应该这样),这可能会成为首选的习语:

return ImmutableList.copyOf(someList);

void (List someList){
    someList = ImmutableList.copyOf(someList);

这有额外的性能,因为copyOf()方法检查集合是否已经是不可变集合的实例(instanceof ImmutableList),如果是,则跳过复制。