美文网首页
创建和销毁对象

创建和销毁对象

作者: 凯诺婷 | 来源:发表于2017-06-03 15:43 被阅读0次

    什么是静态工厂方法

    返回一个类的实例的静态方法

    优势

    • 不要用多态的方法创建构造器,可以选择不同命名的静态工厂方法来创建实例
    • 在类里可以预先构建好实例或者将实例缓存起来,然后重复返回相同对象,不用每次都new一个对象
    • 可以返回子类

    多个构造器解决方案

    假如有2个必选参数和4个可选参数,那么构造函数至少要有5种,而且,每一次选择构造函数的时候还需要注意参数顺序,看api的时候还要点进去看
    方案1:一个空的构造函数,其余参数用set方法来进行赋值,但这个有个不好的地方是,不能保证一个事务
    方案2:builder模式,不直接生成对象,先生成一个builder对象,然后再将builder对象生成目标对象,具体例子如下:

    public class NutritionFacts {
      private final int servingSize; //require
      private final int servings;   //require
      private final int calories;  //optional
      private final int fat;  //optional
      private final int sodium; //optional
      private final int carbohydrate; //optional
      public static class Builder {
        //对象的必选参数
        private final int servingSize;
        private final int servings;
        //对象的可选参数的缺省值初始化
        private int calories = 0;
        private int fat = 0;
        private int carbohydrate = 0;
        private int sodium = 0;
        //只用少数的必选参数作为构造器的函数参数
        public Builder(int servingSize,int servings) {
           this.servingSize = servingSize;
           this.servings = servings;
        }
        public Builder calories(int val) {
           calories = val;
           return this;
        }
        public Builder fat(int val) {
            fat = val;
            return this;
        }
        public Builder carbohydrate(int val) {
            carbohydrate = val;
            return this;
        }
        public Builder sodium(int val) {
            sodium = val;
            return this;
        }
        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
     }
     private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
      }
    }
    //使用方式
    public static void main(String[] args) {
       NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100)
       .sodium(35).carbohydrate(27).build();
       System.out.println(cocaCola);
    }
    

    单例模式

    public class Elvis {
       public static final Elvis INSTANCE = new Elvis();
       private Elivs() { ... }
       public static Elvis getInstance() { 
          return INSTANCE; 
     }
       public void leaveTheBuilding() { ... }
    }
    

    避免创建不必要的对象

    String s = new String("aaa");
    String s = "aaa";
    

    比较这两行代码,上面的语句每次执行的时候都会创建一个新的 String 实例,但是这些创建对象的动作全都是不必要的。而下面的语句只用了一个 String 实例,而不是每次执行的时候都创建一个新的实例。由于 String 被实现为不可变对象,JVM 底层将其实现为常量池,所有值等于"aaa"的对象实例共享同一对象地址,而且还可以保证,对于所有在同一 JVM 中运行的代码,只要他们包含相同的字符串字面常量,该对象就会被重用。
    拓展:string、stringBuilder、stringBuffer的区别
    String 字符串常量
    (每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String)
    StringBuffer 字符串变量(线程安全)对方法加了同步锁

    public synchronized StringBuffer reverse() {
        super.reverse();
        return this;
    }
    public int indexOf(String str) {
        return indexOf(str, 0);        //存在 public synchronized int indexOf(String str, int fromIndex) 方法
    }
    

    *** synchronized的含义:
    每一个类对象都对应一把锁,当某个线程A调用类对象O中的synchronized方法M时,必须获得对象O的锁才能够执行M方法,否则线程A阻塞。一旦线程A开始执行M方法,将独占对象O的锁。使得其它需要调用O对象的M方法的线程阻塞。只有线程A执行完毕,释放锁后。那些阻塞线程才有机会重新调用M方法。这就是解决线程同步问题的锁机制。 ***
    StringBuilder 字符串变量(非线程安全)
    总结
    1.如果要操作少量的数据 <=> String
    2.单线程操作字符串缓冲区 下操作大量数据 <=> StringBuilder
    3.多线程操作字符串缓冲区 下操作大量数据 <=> StringBuffer

    当一个类里面一些对象变量不会改变或者只需要初始化一遍时,可以进行如下操作,将变量初始化为final类型,并在static方法里面完成赋值,重用那些已知不会被修改的可变对象

    public class Person {
       private static final Date BOOM_START;
       private static final Date BOOM_END;
    
       static {
          Calender c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
          c.set(1946,Calendar.JANUARY,1,0,0,0);
          BOOM_START = c.getTime();
          c.set(1965,Calendar.JANUARY,1,0,0,0);
          BOOM_END = c.getTime();
     }
       public boolean isBabyBoomer() {
          return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0;
       }
    }
    

    相关文章

      网友评论

          本文标题:创建和销毁对象

          本文链接:https://www.haomeiwen.com/subject/djnpfxtx.html