如何防止在Java中改变对象的状态(相对于FP)?

时间:2014-12-22 02:17:42

标签: java functional-programming

想象一下,我有这样的方法:

public int doSomething(String value)
{
    this.value = value
    //calculation
    //based on value return the op
    return op;
}

此方法确实会更改对象的状态。在我阅读本书FP In Scala时,作者说,在这种情况下,我们需要将新状态与新对象一起返回。像这样:

public List<Integer,AnClass> doSomething(String value)
{
        AnClass obj = new AnClass();
        obj.value = value
        //calculation
        //based on value return the op
        //return List of op,new AnClass 
}

原因是,doSomething是一种副作用方法,它确实修改了对象的状态。相反,修订版本确实创建了一个新对象,并且不会更改旧对象的value

关于这一点,我几乎没有问题:

  1. 想象一下AnClass有很多实例变量,如果要将它们全部复制到一个新对象中,我应该怎么做?

  2. 我们不应该像作者声称的那样改变对象的状态,这总是好的吗?在这种情况下,我们需要采取类似的方法,如上所述?

  3. 如果我们继续创建java对象,是不是使用了堆内存的负载?这会降低我的申请速度吗?

1 个答案:

答案 0 :(得分:0)

  1. 副本是您正在寻找的流行语。在SO上有几个线程如何在Java中正确地执行它。你使用哪一个取决于类结构。你能保证你班级中包含的每个变量都是不可变的吗?如果是,请选择浅拷贝。如果没有,你别无选择,只能选择更昂贵的深拷贝。

  2. 作为范例的功能性编程可以在副作用或并行化方面为您节省很多麻烦。如果你期待未来有副作用的麻烦或即将修复一些,我会建议使用它。这取决于用例,有时一点点可变性更清晰,更高效。作为一名程序员,您真正了解FP范例,并能够将其应用于适当的案例。你的方法对我来说看起来不太干净。我将在1中指出Java的浅拷贝方法。然后,您应该能够在通过构造函数应用新的AnClass时执行value的副本。您应该无法像在代码中指出的那样更改obj.value,它必须是私有的。之后,您可以调用public int doSomething(AnClass copiedImmutableInstance)方法。那说不知道你的代码的整个上下文。

  3. 是的,但这取决于你是使用深拷贝还是浅拷贝。后者不应该像前者那样产生影响。

  4. 最后我要说的是,Java并非首先用于功能编程。它最近肯定会获得更多功能,但你很难用这种语言实现纯功能。