由于不可变性通常与额外的对象创建联系在一起━━这大部分原因都要"归功"于其不可变性,许多编程人员就断定不可变的对象一定会影响程序的性能。其实真实的情况要复杂得多,实际上,不可变性有时还能够提升程序的性能,可变的对象也能够引起程序性能的下降,可变性对程序性能的影响取决于其使用方式。
程序会经常对文本字符串进行操作和修改━━不可改变性确实是一个麻烦。在每次对String进行操作时━━例如查找或选择一个前缀或子串,把它转换为大写或小写,或者将二个字符串合并成一个新的字符串时,就必须创建一个新的String类对象。
另一方面,我们可以自由地共享一个不可变对象的地址而无需担心对象会被改变,此时,不可变对象在性能上就比可变对象要好许多。
可变对象也存在临时对象问题
在RegExpMatcher中,当一个方法返回的数据类型为String类时,就有必要创建一个新的String类对象。在BadRegExpMatcher中存在的问题之一是match()返回的是一个对象而不是一个简单类型的数据━━因为一个方法返回一个对象,并不意味着一定会创建一个新的对象。考虑一下Point和Rectangle等java.awt中的几何类,一个Rectangle只不过是由四个整数━━左上角点的X、Y坐标以及宽度和高度组成的,AWT组件类存储了组件的位置并通过getBounds()方法将它作为一个Rectangle类对象返回:
public class Component {
...
public Rectangle getBounds();
}
在上面的例子中,getBounds()方法仅仅起一个辅助性作用,它只是声明一些组件内部的有关信息。getBounds()真的必须创建它返回的Rectangle对象吗?也许是这样的吧,我们来看一下getBounds()的编码:
public class Component {
...
protected Rectangle myBounds;
public Rectangle getBounds() { return myBounds; }
}
当有程序调用上面例子中的getBounds()时,并不会创建新的对象,因为组件已经知道它的位置,因此getBounds()是比较高效的。然而,Rectangle的可变性还引起了其他问题,当一个调用它的程序执行下面的代码时会出现什么样的情况呢?
Rectangle r = component.getBounds();
...
r.height *= 2;
文章来源于领测软件测试网 https://www.ltesting.net/