改变方法中的对象参数(在 Java 中)是一种不好的做法吗?

Is mutating object-parameters in a method(in Java) a bad practice?

我有一个关于在方法中改变方法参数(对象)的问题。

我多次读到并听说,在作为参数传入的方法中改变对象是一种不好的做法。例如:

public void modifyList(List<Object> list) {
    list.add(new Object());
}

相反,应该复制传入的对象,对复制的对象执行变异,然后返回复制的对象。例如:

public List<Object> getModifiedList(List<Object> list) {
    List copy = new List<Object();
    //Make a deep copy if it would be necessary
    for(Object o : list) {
        copy.add(o.clone());
    }
    //Modify the copy
    copy.add(new Object());
    //return the copy
    return copy;
}

我知道第二种方法产生副作用的可能性较小,因为它不会改变输入参数。

但这真的是正确的方法吗?性能会受到影响,因为必须创建大量深拷贝。此外,为所有 类 实施复制构造函数和实施克隆方法也将花费大量时间。它还会极大地增加LOC。

实际上我不经常看到这种模式(复制方法参数)。

有经验的人(作为 programmer/software 开发人员工作多年)可以回答这个问题吗?

问候 特立独行

这两种方法都可以,并且根据您的用例可能是正确的选择。只需确保以明确意图的方式命名它们并编写一些 javadoc。

然后由开发人员决定是否可以更改原始列表,如果不行,则传递副本或使用不同的方法。

例如,JDK 中的 this method 改变了现有列表,但其意图和文档非常清楚。

这取决于您的用例,正如您已经暗示的那样。使您的组件不可变会带来许多优势,例如 更好的封装线程安全避免无效状态等.. 当然,通过这种方式您可以实现性能提升。但是有经验的人写了一章,我只能推荐:

Effective Java -

项目 50:在需要时制作防御副本。

他在那里推荐:

You must program defensively, with the assumption that clients of your class will do their best to destroy its invariants.

还有:

In summary, if a class has mutable components that it gets from or returns to its clients, the class must defensively copy these components. If the cost of copy would be prohibitive and the class trusts its clients not to modify the components inappropriately, then the defensive copy may be replaced by documentation outlining the client's responsibility not to modify the affected components.