创建和销毁对象

什么是静态工厂方法

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

优势

  • 不要用多态的方法创建构造器,可以选择不同命名的静态工厂方法来创建实例
  • 在类里可以预先构建好实例或者将实例缓存起来,然后重复返回相同对象,不用每次都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;
   }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 32,469评论 18 399
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 11,947评论 0 62
  • Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参...
    圣骑士wind阅读 2,953评论 0 2
  • 创建和销毁对象概述 何时以及如何创建对象 何时以及如何避免创建对象 如何确保对象适时地销毁 如何管理对象销毁之前必...
    ingot_金果阅读 4,292评论 0 3
  • 现在插播一条新闻: 【今天下午两点钟,警方接到报警,位于长江路馨家园小区二楼住户李先生发现楼上有渗水情况,且水中夹...
    娄兰古城阅读 2,750评论 2 0

友情链接更多精彩内容