Effective 阅读总结

一丶对象的创建和销毁
(一) 静态工厂方法替代构造器
1.静态工厂方法的几大优势:
(1) 静态工厂方法与传统构造器方法不同的第一大优势 ,他们有名称:
sample:返回一个素数
public static int BigInteger.probablePrime(int, int, Random){}

(2)不必再每次调用它的时候都创建一个新的对象:
sample:重复利用 预先创建好的实例,如布尔b
/**
* 1 确保他是一个Singleton
* 2 可用 == 替代 equals,判断相等 提升性能
* @param b
* @return
*/
public static Boolean valueOf(boolean b){
return b ? Boolean.TRUE:Boolean.FALSE;
}

(3)可以返回原返回类型的任何子类型的对象,提高灵活性
sample: java.util.EnumSet 为例子
/**
* 1 如果他的元素<=64 return RegularEnumSet
* 2 否则 return JumboEnumSet
* 3 class RegularEnumSet<E extends Enum> extends EnumSet 都是他的子类
* 4 对客户端不可见 根据参数返回适配类型 更加灵活
* @param elementType
* @param
* @return
*/
public static <E extends Enum> EnumSet noneOf(Class elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");

    if (universe.length <= 64)
        return new RegularEnumSet<>(elementType, universe);
    else
        return new JumboEnumSet<>(elementType, universe);
}

(4) 在创建参数化类型实例的时候,使代码变得更加简洁:
sample:已实例化单个HashMap为例子:
/**
* 传统写法
* 缺点:如果HashMap参数 很多 特别冗长 ,实例化起来写长参数 会很麻烦
*/
Map<String,List> mMap = new HashMap<String, List>();

/**
 * 静态工厂方法
 *      省下了手写实例化后的参数
 */
Map<String,List<String>> mStaticMap = newInstance();

/**
 *  J神说 目前HashMap 并没有工厂方法(可以放自己的工具类中)
 *      在以后java版本中可能会看到
 *      
 * @param <K>
 * @param <V>
 * @return
 */
public static <K,V> HashMap<K,V> newInstance(){
    return new HashMap<K,V>();
}

2丶静态工厂方法的缺点
(1)类如果不含有公有的或者受保护的构造器,就不能被子类化
sample: 比如 Collections 和 Framework, 构造方法私有化 肯定就不能被实例化了。。。。
(2)静态工厂与其他静态方法实际没有任何区别。
sample:
比如你实例化一个TextView 他是通过构造器 实例化的,你找到对应的对象通过Ctrl+左键和容易定位
到 该对象所实例化的构造方法。
但是通过静态工厂 返回给你的实例化对象,是如何实例化的很难找到。
但是J神又说了 Javadoc总有一天会注意到这些静态工厂方法的(但是目前 java8 还没实现 嘻嘻嘻)

(二)遇到多个构造器参数时要考虑用构造器
静态工厂和构造器有个共同的局限性:不能很好的扩展到大量的参数。
(1)从迭代构造器角度考虑:
sample:迭代构造器我们遇到了太多了,比如常见的自定义View

/**

  • 根据传入参数的数量挨个迭代,直到三个参数的构造器为止
  • Created by zhaoyuanchao on 2018/4/21.
    */

public class SampleView extends View {
public SampleView(Context context) {
this(context, null);
}

public SampleView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
}

public SampleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

}

缺点:
构造器调用通常需要许多你根本不想设置的参数,但是由于构造器限制 不得不为他传值, 如果有10个参数那种构造器,就会很快失去控制 相当的不灵活。
(2)JavaBean模式考虑:
sample:可以很好的处理每个必要的可选参数,创建实例容易

/**

  • Created by zhaoyuanchao on 2018/4/21.
    */

public class SampleBean {
private String a;
private String b;

public SampleBean() {
}

public void setA(String a) {
    this.a = a;
}

public void setB(String b) {
    this.b = b;
}

}

缺点:
JavaBean 由于构造过程被分调到了 几个方法中,所以无法通过构造器的有效参数 来保证该类的一致性。
线程不安全。
(3)Builder模式:
sample: 既能保证像构造器那样的安全性,也能保证像JavaBean那样的可读性。

public class NutritionFacts {
private final int a;
private final int b;
private final int c ;
private final int d;
private final int e;
private final int f;

public static class Builder{
    // 如 a b 为必须传入的值
    private final int a;
    private final int b;
    // c d e f为非必须传入的值
    private  int c = 0;
    private  int d = 0;
    private  int e = 0;
    private  int f = 0;

    public Builder(int a , int b) {
        this.a = a;
        this.b = b;
    }

    public Builder setC(int val){
        c = val;
        //这里面为什么要为什么要return 自身呢? 为了方便链式调用复制 c d e f
        return this;
    }
    public Builder setD(int val){
        d = val;
        return this;
    }
    public Builder setE(int val){
        e = val;
        return this;
    }
    public Builder setF(int val){
        f = val;
        return this;
    }

    public NutritionFacts build(){
        return new NutritionFacts(this);
    }
}

private NutritionFacts(Builder builder){
    a = builder.a;
    b = builder.b;
    c = builder.c;
    d = builder.d;
    e = builder.e;
    f = builder.f;
}

}

调用方法:
/**

  • 很常见一种实例化方法吧,我见过很多
    */
    NutritionFacts nutritionFacts = new NutritionFacts.Builder(10, 8).setC(1).
    setD(2).setE(3).setF(4).build();

缺点:
(1)为了创建对象,必须先创建Builder的构造器。
(2)Builder模式比重叠构造器更加冗长,只有在多参的时候才会用到(书上推荐>=4个参数)。
Builder模式的应用场景:
如果类的构造器或者静态工厂中有多个参数,Builder模式就是中不错的选择!

猜你喜欢

转载自blog.csdn.net/u010417597/article/details/85779221