java:示例中不可变对象的优点

Naz*_*rke 4 java immutability

请举例说明我可以看到不可变对象的优点.我在互联网上发现的信息集中在线程中.我还不知道线程.如果例子使用简单的原则会很棒

Jay*_*Jay 11

不可变性在多线程程序中很重要,因为你知道一个线程不会破坏另一个线程中使用的值.但它在单线程程序中也很有用.

这是一个简单的例子:

Integer i=Integer.valueOf(17);
foo(i);
bar(i);
Run Code Online (Sandbox Code Playgroud)

您可能想知道,传递给bar()的值是多少?

假设foo()是一个很大的复杂函数.在这个例子中,我知道一个绝对的事实,当foo完成时,我仍然等于17,因为整数是不可变的.如果不是这样,我将不得不研究foo来判断它是否可能被改变.

这是一个稍微复杂的例子.假设我有一些类似于Integer的对象,但是它是可变的.我们称之为MutableInteger.然后说我写这个:

MutableInteger currentInventory=findQtyInInventory();
MutableInteger neededInventory=currentInventory; // copy current for starters
... bunch of other code ...
neededInventory.subtract(allocatedToSales);
currentInventory.add(arriving);
... bunch of more code ...
if (neededInvenory.compareTo(currentInventory)>0)
  display("Shortage!");
Run Code Online (Sandbox Code Playgroud)

你看到上面的问题了吗?neededInventory和currentInventory指向同一个对象.所有的加法和减法实际上都是在相同的值上,而不是两个不同的值,所以当我们进行测试时,它总是相等的.如果对象是可变的,上面的代码将永远不会工作.如果它们是不可变的,则添加和减去必须返回结果对象而不是在适当的位置更新,这将起作用.

几年前我使用了Fortran编译器,其中整数是可变的.我们有一个接受几个参数的函数,其中一个是整数.在极少数情况下,函数更新整数.然后有一天有人写了一个对这个函数的调用,将常量"2"作为整数传递.该函数决定更新参数,从而将"常量"2改为1!程序中使用常量2的每个其他位置现在神秘地得到值1.调试需要很长时间.


Mic*_*rdt 6

这不是一个可以用例子有用地解释的概念。不可变对象的优点是你知道它们的数据不会改变,所以你不必担心。您可以自由地传递它们,而不必记住您传递给它们的方法是否会以您的代码不准备处理的方式更改它们。这使得处理不可变数据变得更加容易。

对于多线程,这种优势更为重要,因为基于多线程以不应该更改的方式更改数据的错误通常是不可重现的 - 它们取决于时间,因此有时会发生有时不会发生,这使得它们很难分析并修复。