zoukankan      html  css  js  c++  java
  • 《Effective Java》之避免创建不必要的对象

    一.重用不可变的对象

    1.String str="Are You ok?"; //而不是String str=new String("Are You ok?");

    如果字符串的内容不变且该对象需要被多次使用,那么可以使用上面推荐的创建字符串的方式将其放于常量池中(常量池简介)。它可以保证,对于所有在同一虚拟机中运行的代码,只要它们包含相同的字符串字面常量,该对象就会被重用。String str=new String(“Are You ok?”)的创建方式会使每次运行到该句代码(循环或者被多次调用的函数等等)就会重新创建一个String对象。

    2.Boolean isSuccess=Boolean.valueOf("true"); //而不是Boolean isSuccess= new Boolean("true");

    推荐方法使用Boolean的静态成员函数获取它的常量成员Boolean.FALSE或Boolean.TRUE,这样即使你使用了N个Boolean变量,它们依然指向了Boolean类里面仅有的两个声明的常量。
    Boolean isSuccess= new Boolean(“true”);每次调用该句代码都会创建一个Boolean对象。
    静态工厂方法(通过调用该类的静态方法返回一个该类的对象)大多数情况下优于构造器方法

        //JDK1.8中的Boolean类的源码
        public static final Boolean TRUE = new Boolean(true);//常量,初始化一次
        public static Boolean valueOf(String s) {//Java源码
            return parseBoolean(s) ? TRUE : FALSE;
        }

    PS:既然静态工厂方法同一个值返回的是同一个对象,那么下列判断的结果就会是如此。(Integer类会将会缓存-128—-127之间的数值)

      Integer integer1=Integer.valueOf(1);
      Integer integer2=Integer.valueOf(1);      //==是对象引用的比较
      System.out.println(integer1==integer2);    //true
      integer1=new Integer(1);
      integer2=new Integer(1);
      System.out.println(integer1==integer2);   //false
    //JDK1.8中的Integer类的源码
    public static Integer valueOf(int i) {    //low=-128,high=127
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);    //static final Integer cache[];
        }

    二.重用已知不会被修改的对象

    1.善用静态成员变量和常量减少对象的创建

    import java.util.Calendar;
    import java.util.Date;
    import java.util.TimeZone;
    
    public class Person {
        private final Date birthDate;
    
        public Person(Date birthDate) {
            this.birthDate=birthDate;
        }
        //将不会改变的对象声明为静态变量,仅初始化一次而不是声明为函数中的局部变量,那样
        //每一次函数的调用都伴随这种不需要改变的对象的重复创建
        private static final Date BOOM_START;
        private static final Date BOOM_END;
        //应用启动即被初始化,可以使用延迟初始化使isBabyBoomer方法被调用的时候才初
        //始化这些变量
        static {
            Calendar gmtCal=Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            gmtCal.set(1946, Calendar.JANUARY,1,0,0,0);
            BOOM_START=gmtCal.getTime();
            gmtCal.set(1965, Calendar.JANUARY,1,0,0,0);
            BOOM_END=gmtCal.getTime();
        }
        public boolean isBabyBoomer() {
            return birthDate.compareTo(BOOM_START) >=0 &&
                    birthDate.compareTo(BOOM_END) <0;
        }
    }
    

    三.避免无谓的装箱/拆箱操作

    1.优先使用基本数据类型,而不是装箱基本类型,当心无意识的自动装箱。

    public static void main(String []args){
        Long sum=0L;
        for(long i=0; i<Integer.MAX_VALUE;i++){
            sum+=i;//由于sum为Long类型,每次都会对i进行装箱操作
        }
        System.out.printLn(sum);
    }

    参考资料:
    《Effective Java》

  • 相关阅读:
    CSRF 1 (转)
    学习笔记-静态SQL和动态SQL
    学习笔记-oracle-PL/SQL-动态游标
    spring框架介绍以及简单使用
    SpringMvc的常用注解
    tcp的三次握手个四次挥手
    大量面试题
    Comparable和Comparator接口
    JVM介绍
    JVM类加载
  • 原文地址:https://www.cnblogs.com/lizijuna/p/11907417.html
Copyright © 2011-2022 走看看