jvm性能调优(四)-----编写高效的java代码

构造器参数太多怎么办?

可以使用建造者模式,代码示例如下:

public class FoodBuilder {

    //required
    private final String foodName;
    private final int reilang;

    //optional
    private  int danbz;
    private  int dianfen;
    private  int zf;
    private  int tang;
    private   int wss;
    
    private FoodBuilder(Builder builder) {
        foodName = builder.foodName;
        reilang = builder.reilang;
        danbz = builder.danbz;
        //.....     
    }
    
    public static class Builder{
        //required
        private final String foodName;
        private final int reilang;

        //optional
        private  int danbz;
        private  int dianfen;
        private  int zf;
        private  int tang;
        private   int wss;
        
        public Builder(String foodName, int reilang) {
            super();
            this.foodName = foodName;
            this.reilang = reilang;
        }
        
        public Builder danbz(int val) {
            this.danbz = val;
            return this;
        }
        
        //.......
        
        public FoodBuilder build() {
            return new FoodBuilder(this);
        }
    }

    public static void main(String[] args) {
        FoodBuilder foodBuilder = new Builder("food2", 1000).danbz(100)
        //.....
        .build();
    }
}

不需要实例化的类应该构造器私有

对于很多工具类,提供的都是静态方法,需要将构造器私有化,例如jdk中的Arrays类

不要创建不必要的对象 

先看一段代码:

public class Sum {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        
        Long sum = 0L;//对象
        for(long i=0;i<Integer.MAX_VALUE;i++) {
            sum = sum+i;
            //new 20多亿的Long的实例
        }

        System.out.println("spend time:"+(System.currentTimeMillis()-start)+"ms");
    }
}

运行结果:

代码修改下(将Long改成long):

public class Sum {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        
        long sum = 0L;//对象
        for(long i=0;i<Integer.MAX_VALUE;i++) {
            sum = sum+i;
            //new 20多亿的Long的实例
        }

        System.out.println("spend time:"+(System.currentTimeMillis()-start)+"ms");
    }
}

运行结果:

也就是说,在能用基本数据类型的时候就不要用对象,因为对象的创建、销毁(涉及到GC),会大大增加性能损耗。 

避免使用终结方法

就是不要使用Object对象中的finalize方法

protected void finalize() throws Throwable { }

尤其是在这个方法里面写逻辑,例如回收资源等,因为虚拟机不保证这个方法能及时被执行,或者说被执行。

使类和成员的可访问性最小化

主要目的就是解耦。

当心字符串连接的性能

public class Test {
    private static class Log{
        public static void debug(String msg){
            if (isDebug()) System.out.println(msg);
        }

        public static boolean isDebug(){
            return false;
        }
    }

    public static void main(String[] args) {
        int count = 10000000;
        long start = System.currentTimeMillis();

        for(int i = 0;i<count;i++){
            Log.debug("The system is running and the time is "
                    +System.currentTimeMillis()
                    +" now,Let's do another thing:"+System.nanoTime());
        }
        System.out.println("直接打印模式,次数:"+count+":spend time :"
                +(System.currentTimeMillis()-start)+"ms");

        start = System.currentTimeMillis();
        for(int i = 0;i<count;i++){
            if(Log.isDebug())
                Log.debug("The system is running and the time is "
                        +System.currentTimeMillis()
                    +" now,Let's do another thing:"+System.nanoTime());
        }
        System.out.println("先判断再打印模式,次数:"+count+":spend time :"
                +(System.currentTimeMillis()-start)+"ms");
    }
}

运行结果:

解释:上面的isDebug()一直返回的是false,所以下面一种写法不需要去拼接字符串,大大节省时间。这也是大部分开源框架(spring、mybatis等)打印日志前都会判断的一个原因。 并且如果字符串拼接过长的情况下,使用StringBuilder或StringBuffer。

原文地址:https://www.cnblogs.com/alimayun/p/12342511.html