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

创建和销毁对象

作者: 凯诺婷 | 来源:发表于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;
   }
}

相关文章

  • EffectJava翻译系列(第一章:创建和销毁对象)

    1.创建和销毁对象 这个章节包含创建和销毁对象,什么时候和怎样创建,什么时候避免创建,如何确保对象在准确的时机销毁...

  • Effective Java Note (对象的创建和销毁)

    Effective Java Note (对象的创建和销毁) 一、对象的创建和销毁 1. 考虑使用静态工厂方法替代...

  • 优雅地创建和销毁对象

    创建和销毁对象概述 何时以及如何创建对象 何时以及如何避免创建对象 如何确保对象适时地销毁 如何管理对象销毁之前必...

  • 创建和销毁对象

    1、何时以及如何创建对象? 2、何时以及如何避免创建对象? 3、如何确保它们能够适时地销毁,以及如何管理对象销毁之...

  • 创建和销毁对象

    避免创建不必要的对象 重用不可变对象和已经的不会被修改的对象 考虑下面的语句String s=new String...

  • 创建和销毁对象

    考虑用静态工厂方法代替构造函数 静态工厂方法只是一个简单的静态方法,它返回的是类的一个实例 三个优点 静态工厂方法...

  • 创建和销毁对象

    学习目的: 何时以及如何创建对象 何时以及如何避免创建对象 如何确保对象适时销毁 如何管理对象销毁前必须进行的各种...

  • 创建和销毁对象

    相比于构造函数,考虑使用静态工厂方法 如果自己写的类,希望客户端能创建它的实例,一般自己要提供哪些方式? 提供公有...

  • 创建和销毁对象

    什么是静态工厂方法 返回一个类的实例的静态方法 优势 不要用多态的方法创建构造器,可以选择不同命名的静态工厂方法来...

  • 创建和销毁对象

    第一条:考虑用静态工厂方法代替构造器。 第二条:遇到多个构造器参数时要考虑用构造器。 第三条:用私有构造器或者枚举...

网友评论

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

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