java开发规范和优化总结

来源:互联网 发布:mysql 查看权限 编辑:程序博客网 时间:2024/06/11 11:56

1、由于String类的不可变性质,当String变量需要经常变换其值时,应该考虑使用StringBuilder类,以提高程序效率。

2、尽量使用基本数据类型(byte,short,int,long,float,double,char,boolean)

3、尽量减少对变量的重复计算

   for (int i = 0; i < list.size(); i++){....}
   建议替换为:

   for (int i = 0, int length = list.size(); i < length; i++){....}
   这样,在list.size()很大的时候,就减少了很多的消耗

4、不要在循环中使用try…catch…,应该把其放在最外层

5、乘法和除法使用移位操作:

     例如:for (val = 0; val < 100000; val += 5){
a = val * 8;
b = val / 2;
}
用移位操作可以极大地提高性能,因为在计算机底层,对位的操作是最方便、最快的,因此建议修改为:
for (val = 0; val < 100000; val += 5){
a = val << 3;  //左移一个 相当于乘以2的0次方,2个就是2的次方,以此类推
b = val >> 1; //右移一个 相当于除以2的0次方,2个就是2的次方,以此类推
}
移位操作虽然快,但是可能会使代码不太好理解,因此最好加上相应的注释。

6、循环内不要不断创建对象引用:

     例如:for (int i = 1; i <= count; i++){
Object obj = new Object();
}
这种做法会导致内存中有count份Object对象引用存在,count很大的话,就耗费内存了,建议为改为:
Object obj = null;
for (int i = 0; i <= count; i++) {
obj = new Object();
}
这样,内存中只有一份Object对象引用,每次new Object()的时,Object对象引用指向不同的Object罢了,但是内存中只有一份,这样就大大节省了内存空间。

7、基于效率和类型检查的考虑,应该尽可能使用array,无法确定数组大小时才使用ArrayList

8、尽量避免随意使用静态变量:及时清除不再需要的会话

   当某个对象被定义为 static 的变量所引用,那么 gc 通常是不会回收这个对象所占有的堆内存的,如:
public class A{
private static B b = new B();
}
   此时静态变量b的生命周期与A类相同,如果A类不被卸载,那么引用B指向的B对象会常驻内存,直到程序终止。

9、及时清除不再需要的会话

为了清除不再活动的会话,许多应用服务器都有默认的会话超时时间,一般为30分钟,当应用服务器需保存更多会话时,如果内存不足,那么操作系统会把部分数据转移到磁盘,应用服务器也可能根据MRU(最近最频繁使用)算法把部分不活跃的会话转储到磁盘,甚至可能抛出内存不足异常,如果会话要被转储到磁盘,那么必须要先被序列化,在大规模集群中,对对象进行序列化代价是很昂贵的,因此,当会话不再需要时,应当及时调用HttpSession的invalidate()方法清除会话

10、实现RandomAccess接口的集合比如ArrayList,应当使用最普通的for循环而不是foreach循环来遍历:

这是JDK推荐给用户的,JDK API对于RandomAccess接口的解释是:实现RandomAccess接口用来表明其支持快速随机访问,此接口的主要目的是允许一般的算法更改其行为,从而将其应用到随机或连续访问列表时能提供良好的性能,实际经验表明,实现RandomAccess接口的类实例,假如是随机访问的,使用普通for循环效率将高于使用foreach循环,反过来,如果是顺序访问的,则使用Iterator会效率更高。

if(list instanceof RandomAccess){ //java中instanceof关键字,表示的是 前者是否是后者的一个实例
for(int i=0;i<list.size();i++){ }
}else{
Iterator<?> iterator=list.iterable();
while(iterator.hasNext()){
iterator.next();
}
}

foreach循环的底层实现原理就是迭代器Iterator,如果是顺序访问的,则使用Iterator会效率更高

11、将常量声明为static final,并以大写命名

这样在编译期间就可以把这些内容放入常量池中,避免运行期间计算生成常量的值,另外,将常量的名字以大写命名也可以方便区分出常量与变量

12、使用带缓冲的输入输出流进行IO操作:

带缓冲的输入输出流,即BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,这可以极大地提升IO效率

13、顺序插入和随机访问比较多的场景使用ArrayList,元素删除和中间插入比较多的场景使用LinkedList:

14、不要让public方法中有太多的形参:

public方法即对外提供的方法,如果给这些方法太多形参的话主要有两点坏处:
(1)违反了面向对象的编程思想,Java讲求一切都是对象,太多的形参,和面向对象的编程思想并不契合
(2)参数太多势必导致方法调用的出错概率增加,至于这个”太多”指的是多少个,3,4个吧,比如我们用JDBC写一个insertStudentInfo方法,有10个学生信息字段要插如Student表中,可以把这10个参数封装在一个实体类中,作为insert方法的形参

15、字符串变量和字符串常量equals的时候将字符串常量写在前面(这么做主要是可以避免空指针异常)

16、把一个基本数据类型转为字符串,基本数据类型.toString()是最快的方式,String.valueOf(数据)次之,数据+””最慢:

17、使用最有效率的方式去遍历Map:

遍历Map的方式有很多,通常场景下我们需要的是遍历Map中的Key和Value,那么推荐使用的,效率最高的方式是:
HashMap<String,String> hm=new HashMap<String,String>();
hm.put("111","222");

//如果你只是想遍历一下这个Map的key值,那用”Set<String> keySet = hm.keySet();”会比较合适一些
Set<Map.Entry<String,String>> entrySet=hm.entrySet();
Iterator<Map.Entry<String,String>> iter=entrySet.iterator();
while(iter.hasNext()){
Map.Entry<String,String> entry=iter.next();
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
18、对资源的close()建议分开操作:

try{
XXX.close();
YYY.close();
}catch(Exception e){ }
//建议改为:
try{
XXX.close();
}catch(Exception e){ }

try{
YYY.close();
}catch(Exception e){ }
虽然有些麻烦,却能避免资源泄露,我们想,如果没有修改过的代码,万一XXX.close()抛异常了,那么就进入了cath块中了,
YYY.close()不会执行,YYY这块资源就不会回收了,一直占用着,这样的代码一多,是可能引起资源句柄泄露的,而改为下面的写法之后,就保证了无论如何XXX和YYY都会被close掉

原创粉丝点击