对java编程应注意的基本优化

摘自android应用开发解密一书中。


[1] 尽量指定类的final修饰符。带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。如果指定一个类为final,该类的所有方法都是final。java编译器会寻找机会内联所有的final方法。此举能够使性能提高平均50%。
[2]尽量重用对象。特别是String对象的使用中,出现了字符串连接情况时应使用StringBuffer代替。由于系统不仅要花时间生成对象,以后可能还要花时间对这些对象进行垃圾回收和处理。
[3]尽量使用局部变量。调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中,速度较快。其它变量,如静态变量、实例变量等,都在堆中创建,速度较慢,
[4]不要重复初始化变量。
[5]在Java+Oracle的应用系统中,java中内嵌的SQL语句尽量使用大写形式,以减轻Oracle解析器的解析负担。
[6]java编程中,进行数据库连接、I/O流操作时务必小心,在使用完毕时及时关闭以释放资源。
[7]由于JVM的有其自身的GC机制,不需要程序员的过多考虑,从一定程度上减轻了开发者负担,但同时也遗漏了隐患,过分的创建对象需要消耗系统大量的内存,严重时会导致内存泄露,因此保证过期对象的回收具有重要意义。JVM回收对象垃圾的条件是:对象不被引用,然而JVM并不是十分明智,即使对象满足了垃圾回收的条件也不一定会立刻被回收。所以建议在对象使用完毕后,手动设置成null。
[8]在使用同步机制时,应尽量避免使用方法同步代替代码块同步。
[9]尽量减少对变量的重复计算。
例如
for(int i=0;i<list.size();i++){
......
}
应代替为:
for(int i=0,int len=list.size();i<len;i++){
......
}
[10]尽量采用lazy loading的策略,在需要的时候才开始创建。
例如:
String str="aaa"
if(i==1){
list.add(str);
}
应替换为if(i==1){
String str="aaa"
list.add(str);
}
[11]慎用异常。异常对性能不利。抛出异常首先要创建一个新的对象,Throwable接口的构造函数调用名为fillInStackTrace()本地方法,fillInStackTrace()方法检查栈,搜集调用跟踪信息。
[12]不要在循环中使用Try/Catch语句,应将其放在最外层。
[13]StringBuffer的使用,StringBuffer表示了可变的、可写的字符串。有三个构造方法。
StringBuffer();
StringBuffer(int size);
StringBuffer(String str);
你可以通过、stringBuffer的构造函数来设置其初始化容量,这样可以明显提高其性能。这里提到的构造函数是StringBuffer(int Length),length表示当前StringBuffer能够保持的字符数量。首先我们来看一下Stringbuffer的默认行为。StringBuffer在内部维护一个字符数据时,当你使用缺省的构造函数时,因为没有设置初始化字符长度,StringBuffer的被初始化为16个字符,也就是说缺省容量为16个字符。当达到最大容量时。它会将自身容量增加到当前的2倍再加2,也就是16*2+2=34个字符,当追加到34个字符时,其会追加容量为34*2+2=70个字符。所以这样的代价是很昂贵的。所以应给StringBuffer设置一个适当的初始化容量。
[14]合理使用Java类Java.util.Vector。简单的说,一个Vector就是java.lang.Object实例数据。Vector与数组相似,它的元素可以通过整数形式的索引访问。但是,vector类型的对象在创建之后,对象达大小以元素的增加或者删除而定。请考虑下面这个向vector加入元素的例子。
Object obj=new object();
Vector v=new Vector(100000);
for(int i=0;
i<100000;i++){v.add(0,obj);}

除非有绝对充足的理由要求每次都把新元素插入Vector的前面,否则上面的代码对性能不利。在默认构造函数中,Vector的初始化存储能力是10个元素,如果新元素加入时存储能力不足,则之后存储能力每次加倍。vector和StringBuffer一样。
[15]当复制大量数据时,使用System.arraycopy()命令。
[16]代码重构:增强代码的可读性。
例如:
pulic class ShopCart{
private List carts;
public void add(Object item){
if(carts==null){
carts=new ArrayList();
}
carts.add(item);
}
public void remove(Object item){
if(carts.contains(item)){
carts.remove(item);
}
}
public List getCarts(){
//返回只读列表
return Collections.unmodifiableList(carts);
}
//不推荐这种方式
//this.getCarts().add(item);
}

[17]不用new关键词创建实例化类的实例
使用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用。但如果一个对象实现了Cloneable接口,我们可以调用它的clone()方法。clone()方法不会调用任何类构造函数。
[18]乘法和除法。
考虑下面的代码:
for(val=0;val<10000;val+=5){
alterX=val*8;myResult=val*2;
}
用位移操作代替乘法操作可以极大的提高性能,下面是修改后的代码。
for(val=0;val<10000;val+=5){
alterX=val<<3;myResult=val<<1;
}

[19]不要声明数组为public static final。
[20] array(数组)和ArrayList的使用。array最高效,但其是固定容量且无法动态更改;ArrayList容量可动态增长但牺牲效率。
[21]尽量使用HashMap和ArrayList,除非必要不推荐使用HashTable和Vector,后者由于使用了同步机制,从而导致了性能的开销。
[22]StringBuffer和StringBuilder的区别在于:StringBuffer线程安全的可变字符序列。一个类似于String的字符串缓冲区,但不能修改。StringBuilder与该类相比,通常应该优先使用、stringbuilder,因为它支持所有相同的操作,但不执行同步,所以速度快些。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值