Java程序性能优化总结--------对象篇

来源:互联网 发布:淘宝安卓下载 编辑:程序博客网 时间:2024/04/30 20:35

1.生成对象时,分配合理的空间和大小

  Java中的很多类都有它的默认的空间分配大小,对于一些有大小的对象的初始化,应该预计对象的大小,然后使用进行初始化,上面的例子也说明了这个问题,StringBuffer创建时,我们指定了它的大小。

  另外的一个例子是Vector,当声明Vector vectnew Vector()时,系统调用:

public Vector() {// 缺省构造函数
 this(10); // 容量是 10;
}

  缺省分配10个对象大小容量。当执行add方法时,可以看到具体实现为:..

public synchronized boolean add(Object o) {
 modCount++;
 ensureCapacityHelper(elementCount+1);
 elementData[elementCount++] =o;

 return true;
}

private void ensureCapacityHelper(int minCapacity) {
 int oldCapacity = elementData.length;
 if (minCapacity oldCapacity) {
  Object oldData[] = elementData;
  int newCapacity = (capacityIncrement 0) ? (oldCapacity + capacityIncrement) :
(oldCapacity * 2);
  if (newCapacity minCapacity) {
   newCapacity = minCapacity;
  }
  elementData = new Object[newCapacity];
  System.arraycopy(oldData, 0, elementData, 0, elementCount);
 }
}

  我们可以看到,当Vector大小超过原来的大小时,一些代码的目的就是为了做容量的扩充,在预先知道该Vector大小的话,可以指定其大小,避免容量扩充的开销,如知道Vector大小为100时,初始化是就可以象这样。

Vector vect .. new Vector(100);

 

2.对象的创建尽量少用new来初始化类的实例

  尽量少用new来初始化一个类的实例,当一个对象是用new进行初始化时,其构造函数链的所有构造函数都被调用到,所以new操作符是很消耗系统资源的,new一个对象耗时往往是局部变量赋值耗时的上千倍。同时,当生成对象后,系统还要花时间进行垃圾回收和处理。

所以,在需要的时候声明它,初始化它,不要重复初始化一个对象,尽量能做到再使用,而用完后置null有利于垃圾收集。

一个重用对象的方法是改变对象的值,如可以通过setValue之类的方法改变对象的变量达到重用的目的


替代办法:让类实现Cloneable接口,同时采用工厂模式,将减少类的创建,每次都是通过clone()方法来获得对象。另外使用接口也能减少类的创建。对于成员变量的初始化也应尽量避免, 特别是在一个类派生另一个类时。


  尽量在使用时再创建该对象。如:

NewObject object = new NewObject();
int value;
if(i
0 )
{
 value =object.getValue();
}

  可以修改为:

int value;
if(i
0 )
{
 NewObject object = new NewObject();
 Value =object.getValue();
}

 

3. 避免不需要的造型操作(强制类型转化)

所有的类都是直接或者间接继承自Object。同样,所有的子类也都隐含的等于其父类。那么,由子类造型至父类的操作就是不必要的了。
例子:

class UNC {
   String _id = "UNC";
}
class Dog extends UNC {
   void method () {
       Dog dog = new Dog ();
       UNC animal = (UNC)dog;  // not necessary.
       Object o = (Object)dog;         // not necessary.
   }
}

 
修改为: 

    
class Dog extends UNC {
   void method () {
       Dog dog = new Dog();
       UNC animal = dog;
       Object o = dog;
   }
}

 



 

4.避免不需要的instanceof操作


如果左边的对象的静态类型等于右边的,instanceof表达式返回永远为true
       
例子:     
  
public class UISO {

 public UISO () {}

}
class Dog extends UISO {
   void method (Dog dog, UISO u) {
       Dog d = dog;
       if (d instanceof UISO) // always true.
           System.out.println("Dog is a UISO");
       UISO uiso = u;
       if (uiso instanceof Object) // always true.
           System.out.println("uiso is an Object");

   }
}
       
更正: 

    
删掉不需要的instanceof操作。
       
class Dog extends UISO {
   void method () {
       Dog d;
       System.out.println ("Dog is an UISO");
       System.out.println ("UISO is an UISO");
   }
}

 

5.与一个接口进行instanceof操作


基于接口的设计通常是件好事,因为它允许有不同的实现,而又保持灵活。只要可能,对一个对象进行instanceof操作,以判断它是否某一接口要比是否某一个类要快。

例子:
public class INSOF {

   private void method (Object o) {
       if (o instanceof InterfaceBase) { }  // better
       if (o instanceof ClassBase) { }   // worse.
   }
}

class ClassBase {}
interface InterfaceBase {}