添加较小的辅助性函数
在最初版本的Swing工具包中创建过多的PointRectangle和Dimension对象会严重地影响程序的性能尽管一次在一个Point或Rectangle对象中返回多个值似乎更有效率但这样作的代价要比调用多个方法高得多在最近的Swing版本推出之前这个问题可以通过简单地在组件或其他类中添加一些辅助性的方法得到改善如下所示
public int getX() { return myBoundsx; }
public int getY() { return myBoundsy; }
public int getHeight() { return myBoundsheight; }
public int getWidth() { return myBoundswidth; }
现在调用程序可以在不创建临时对象的情况下得到同样的结果如下所示
int x = componentgetX();
int y = componentgetY();
int h = componentgetHeight();
int w = componentgetWidth();
原来的getBounds()仍然可以使用较小的辅助性函数只不过提供了一种实现同样目标的效率更高的方法其结果是Rectangle的接口将完全暴露在组件的接口中当修改Swing使之支持并可以使用这些较小的辅助性函数后其结果是Swing中的许多操作的运行速度都比原来快了二倍由于GUI代码对性能比较敏感这一改进的意义是重大的
这种技术带来的负作用是对象拥有的方法更多了而且要获取同一种信息可以有多种方法这就使文件变得相当大而且也更加复杂了不利于用户采用这一技术但是象Swing的例子显示的那样在对性能要求比较高的情况下这种优化技术还是十分有效的
可变性的利用
除了在组件中添加象上面讨论的getX()等具有简单数据类型值的临时函数外Java 还使用了其他的技术来减少在AWT和Swing中的对象创建活动在组件和其他的GUI类中添加另一种版本的getBounds()就可以在没有创建临时对象的前提上使调用程序得到象Rectangle类型的返回值
public Rectangle getBounds(Rectangle returnVal) {
returnValx = myBoundsx;
returnValy = myBoundsy;
returnValheight = myBoundsheight;
returnValwidth = myBoundswidth;
return returnVal;
}
调用程序仍然必须创建一个Rectangle对象不过可以在以后的调用中重用它如果一个调用程序反复调用许多Component对象就可以创建一个Rectangle对象并在每个Component中使用它需要注意的是这一技术只适用于可变的对象类型不可能通过这种方式减少创建String类对象
结合二家之长
一个更好的解决Point等简单类的对象创建问题的方法是使得Point类成为不可变的然后再定义一个可变的子类具体方法如下面的例子所示
public class Point {
protected int x y;
public Point(int x int y) { thisx = x; thisy = y; }
public final int getX() { return x; }
public final int getY() { return y; }
}
public class MutablePoint extends Point {
public final void setX(int x) { thisx = x; }
public final void setY(int y) { thisy = y; }
}
public class Shape {
private MutablePoint myLocation;
public Shape(int x int y) { myLocation = new MutablePoint(x y); }
public Point getLocation() { return (Point) myLocation; }
}
在上面的例子中Shape可以安全地返回myLocation的地址因为调用程序如果试图修改这些域或调用他们的调节器就会返回一个出错信息当然调用程序仍然可以将Point转换为MutablePoint但很明显这会带来不安全性虽然调用程序也会得到它们所需要的返回值)C++的开发人员会注意到这一技术与C++中的返回一个Rectangle的常量地址(const Rectangle&)有点类似━━Java不具备这样的特性
在Java 类库中的javamathBigInteger类中一个类无需创建新的对象就返回一个只读的对象MutableBigInteger类不是公开的它只供javamath类库内部使用但由于BigInteger类中的一些方法(例如gcd())是由许多的算术操作组成的完成这些操作而无需创建临时对象将极大地改善程序的性能