Java代码优化

代码优化的目标是:

1、减小代码的体积

2、提高代码运行的效率

(1)重用对象 特别是String对象的使用,出现字符串连接时应该使用StringBuilder/StringBuffer代替。 由于Java虚拟机不仅要花时间生成对象,以后可能还需要花时间对这些对象进行垃圾回收和 处理,因此,生成过多的对象将会给程序的性能带来很大的影响。

String是不可变字符串,StringBuffer是可变字符串,String的不变会导致字符串操作过程 中不断创建字符串,产生新的字符串需要做大量的工作:内存空间分配,

String str = “abc”; 
String strString = str + “123456789”; 
jvm会在堆内存中开辟3个空间,1为“abc”,2为“ccd”,3为“abcccd”,最终str2指向3, 1和2因为没有被引用,会在GC回收机制内被回收,而GC的开销是相当大的,所以应尽量避免,
那么使用StringBuffer是什么情况呢? 
StringBuffer str =“abc”; 
str.append(“ccd”) 
jvm只会在堆空间中开辟一个空间“abc”,执行append时只会在“abc”的空间上+“ccd” 因此避免了GC的回收,也避免了内存的浪费 同样是为了获取到“abcccd”,但第二种方式明显更有效率 那怎么判断是使用StringBuffer还是StringBuilder的呢? 如果有线程安全的考虑使用StringBuffer,无则使用StringBuilder,线程安全也是一个比较高的开销 

(2)及时关闭流 Java编程过程中,进行数据库连接、I/O流操作时务必小心,在使用完毕后,及时关闭以释放 资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎,将会导致严重的后果。

(3)循环内不要不断创建对象引用

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();

}

(4)使用数据库连接池和线程池 这两个池都是用于重用对象的,前者可以避免频繁地打开和关闭连接,后者可以避免频繁地创建 和销毁线程。

(5)使用带缓冲的输入输出流进行IO操作 带缓冲的输入输出流, 即BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream, 这可以极大地提升IO效率

(6)尽可能使用局部变量 调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中速度较快,其他变量,如静态 变量、实例变量等,都在堆中创建,速度较慢。另外,栈中创建的变量,随着方法的运行结束, 这些内容就没了,不需要额外的垃圾回收。

(7)尽量减少对变量的重复计算

for (int i = 0; i < list.size(); i++)

{...} 建议替换为:

for (int i = 0, int length = list.size(); i < length; i++)

{...}

这样,在 list.size() 很大的时候,就减少了很多的消耗(减list.size()的计算)

(8)尽量采用懒加载的策略,即在需要的时候才创建 例如:

String str = "aaa";

if (i == 1){

        list.add(str);

} 建议替换为:

if (i == 1){

String str = "aaa";

list.add(str);

}

(9)不要在循环中使用 try…catch…,应该把其放在最外层 因为try-catch放在循环里面,如果出现异常的话,循环会继续执行;try-catch放在循环 外面的话,出现异常会终止循环;

(10)乘法和除法使用移位操作 例如: for (val = 0; val < 100000; val += 5){ a = val * 8; b = val / 2; } 用移位操作可以极大地提高性能,因为在计算机底层,对位的操作是最方便、最快的, 因此建议修改为:

for (val = 0; val < 100000; val += 5){

        a = val << 3;

        b = val >> 1;

}

(11)尽量使用非线程安全集合 尽量使用 HashMap、ArrayList、StringBuilder,除非线程安全需要,否则不推荐 使用 Hashtable、Vector、StringBuffer,后三者由于使用同步机制而导致了性能开销;

(12)尽量避免随意使用静态变量 要知道,当某个对象被定义为 static 的变量所引用,那么 gc 通常是不会回收这个对 象所占有的堆内存的,如:

public class A{

        private static B b = new B();

} 此时静态变量 b 的生命周期与 A 类相同,如果 A 类不被卸载,那么引用 B 指向 的 B 对象会常驻内存,直到程序终止;

(13)实现了RandomAccess这个接口的 List,那么使用for循环的方式获取数据会优于 用迭代器(foreach循环以及Iterator迭代器循环)获取数据。 例如实现RandomAccess(持快速随机访问策略)接口的ArrayList类 数据量不大的时候,按习惯使用性能差距不大;

(14)使用同步代码块替代同步方法 除非能确定一整个方法都是需要进行同步的,否则尽量使用同步代码块,避免对那些不需 要进行同步的代码也进行了同步,影响了代码执行效率。

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

(16)不要创建一些不使用的对象,不要导入一些不使用的类 如果代码中出现“The value of the local variable i is not used”、 ”The import java.util is never used”,那么请删除这些无用的内容

(17)程序运行过程中避免使用反射 反射是 Java 提供给用户一个很强大的功能,功能强大往往意味着效率不高。不建议在程 序运行过程中使用尤其是频繁使用反射机制,特别是 Method 的 invoke 方法,如果确实 有必要,一种建议性的做法是将那些需要通过反射加载的类在项目启动的时候通过反射实例 化出一个对象并放入内存—- 用户只关心和对端交互的时候获取最快的响应速度,并不关心 对端的项目启动花多久时间。

(18)字符串变量和字符串常量 equals 的时候将字符串常量写在前面 如以下代码:

String str = "123";

if (str.equals("123")) { ... }

建议修改为:

String str = "123";

if ("123".equals(str)){ ... }

可以避免空指针异常

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

(20)使用最有效率的方式去遍历 Map--方法三使用迭代器速度最快

private void foreachKeyset(Map<Integer, String> map) {

        for(Integer key : map.keySet()){ String value = map.get(key); //                 System.out.println("foreachKeyset : key :" + key + "---> value :"+ value); }

        }

private void foreachEntry(Map<Integer, String> map) {

        for(Entry<Integer, String> entry : map.entrySet()){ //

                System.out.println("foreachEntry : key :" + entry.getKey() + "---> value :"+entry.getValue());

} }

private void iteratorEntry(Map<Integer, String> map) {

        Iterator<Entry<Integer, String>> iterator = map.entrySet().iterator();

        while(iterator.hasNext()){

                Entry<Integer, String> entry = iterator.next(); //

                System.out.println("iteratorEntry : key :" + entry.getKey() + "---> value :"+entry.getValue()); } }

(21)使用return和continue来终止方法或跳出循环 如某些情况下id为空直接return终止,不往下走

if(id == ""){

return;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值