“通过引用”编辑对象的好习惯?

时间:2010-07-15 08:02:08

标签: java pass-by-reference pass-by-value

假设我有一个名为Superstar的类型。现在我希望有一个方法可以完成一些工作并编辑Superstar对象的一些属性。

以下是我如何实现这一点的两种方法。方式1将如下:

private Superstar editSuperstar(Superstar superstar){
    ....
    superstar.setEdited(true);
    return superstar;
}
...
superstar = editSuperstar(superstar);

方式2就是这样:

private void editSuperstar(Superstar superstar){
    ....
    superstar.setEdited(true);
}
...
editSuperstar(superstar);

这两种可能方式中的哪一种被认为是“最佳做法”?第一个,或第二个伪“引用”一个?

5 个答案:

答案 0 :(得分:6)

在您的情况下,第二种形式是可取的,因为您直接更改了其中一个超级巨星属性(edited)。但是,如果你有一个方法使用超级巨星对象并返回它的更新版本(不更改初始对象),第一个表单将有利于我。

最后,由于这两个示例都只使用Superstar对象,因此它们应该是Superstar类的成员方法。

答案 1 :(得分:4)

使用方式2,除非您要创建一个打算链接调用的“构建器”类。例如:

MyClass c = (new MyClassBuilder()).setX(blah).setY(blah).build();

答案 2 :(得分:4)

第一种形式具有欺骗性。它给人的印象是传入一个对象,然后复制该对象,然后更改并返回副本。

“最佳实践”是使用第一种形式,但要实际执行隐含的内容(将更改应用于副本,然后返回)。不可变对象通常应优先于可变对象,除非它们是复制成本高的大块东西,在这种情况下,你应该支持第二种形式。

答案 3 :(得分:2)

你在第一种方法遇到的问题是如果你这样使用它:

Superstar edited = editSuperstar(originalSuperstar);

这也将修改原始的超级明星,在我看来,这是违反直觉的......

因此,如果您修改传递的对象,则更喜欢第二个,如果您返回该对象的新副本,则更喜欢第一个。

对于这个特殊的例子,你可以简单地将一个编辑方法添加到Superstar类......

答案 4 :(得分:1)

如果返回仅更改了某些字段的同一实例,则第一种形式对于API客户端来说会令人惊讶。人们希望在不更改原始实例的情况下获得修改后的副本。

因此,如果您没有返回副本,请使用第二个表单,如果您这样做,请使用第一个表单(并考虑在这种情况下使Superstar不可变)。