美文网首页
1.考虑用静态工厂方法代替构造器

1.考虑用静态工厂方法代替构造器

作者: 哲学与豆包 | 来源:发表于2018-01-31 17:37 被阅读0次

静态方法与构造器不同的第一大优势在于,它们有名称

对于类的构造器来说他们的名字一定是一样的

下面的例子中 无论是戴眼镜的人还是不戴眼镜的人,他们都是通过NEW的时候传进来的参数.但是这样很不明确,构造器并没有完美的表达这个意思,可读性很差.

   public class person {
    private String name;
    private int sex;
    private boolean glasses;

    // 普通的人
    public person(String name, int sex) {
        this.name = name;
        this.sex = sex;
    }

    // 带眼镜的人
    public person(String name, int sex, boolean glasses) {
        this.name = name;
        this.sex = sex;
        this.glasses = glasses;
    }
}

我们来看看作者举的一个正面的例子

    // BigInteger构造方法 这个方法可能会返回素数 语义表达不明确
    public BigInteger(int bitLength, int certainty, Random rnd) {
        BigInteger prime;

        if (bitLength < 2)
            throw new ArithmeticException("bitLength < 2");
        prime = (bitLength < SMALL_PRIME_THRESHOLD
                                ? smallPrime(bitLength, certainty, rnd)
                                : largePrime(bitLength, certainty, rnd));
        signum = 1;
        mag = prime.mag;
    }
  
    //所以在最后BigInteger 提供了一个静态方法 这个方法名清晰的告诉了我们可能是返回素数的
    public static BigInteger probablePrime(int bitLength, Random rnd) {
        if (bitLength < 2)
            throw new ArithmeticException("bitLength < 2");

        return (bitLength < SMALL_PRIME_THRESHOLD ?
                smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
                largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));
    }

静态工厂方法与构造器不同的第二大优势在于,不必在每次调用它们的时候都创建一个新的对象

我们知道既然你调用了构造方法那肯定是会新建一个对象的,但是用静态工厂方法就不一定了,我们可以先将对象缓存起来

这个例子是Boolean类的

    public static final Boolean TRUE = new Boolean(true);

    public static final Boolean FALSE = new Boolean(false);

    // 直接返回了保存好的对象
    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

静态工厂方法与构造器不同的第三大优势在于,他们可以返回原返回类型的任何子类型的对象

RegularEnumSet 和 JumboEnumSet 全部都是继承自EnumSet

   public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
       Enum<?>[] universe = getUniverse(elementType);
       if (universe == null)
           throw new ClassCastException(elementType + " not an enum");
       // 返回一个EnumSet子类
       if (universe.length <= 64)
           return new RegularEnumSet<>(elementType, universe);
       else
           return new JumboEnumSet<>(elementType, universe);
   }

本段落还有一个例子, 现在我并没有看懂,也并没有懂适配器模式,所有以后再来补充

静态工厂第四大优在于,在创建参数化类型实例的时候,它们使代码变得更加简洁

这一点现在已经不存在了,但还是举个例子

    // java1.7以前 即使泛型已经规定好了数据类型,但是你还是要写出来
    List<String>  list = new ArrayList<String>();

    // java1.7以后
    List<String> list = new ArrayList<>();

    // Guava Lists静态工厂方法 
    public static <E> ArrayList<E> newArrayList(E... elements) {
        checkNotNull(elements); 
        int capacity = computeArrayListCapacity(elements.length);
        ArrayList<E> list = new ArrayList<>(capacity);
        Collections.addAll(list, elements);
        return list;
    }

    //调用 通过静态方法工厂就不需要写出来了
    List<String> list = Lists.newArrayList("1");

静态工厂方法的主要缺点在于,类如果不含公有的或者受保护的构造器,就不能被子类化

如果构造器为私有的,通过静态方法来获得对象,那么该类是没有办法子类化的,也就是说无法继承.

静态工厂方法的第二个缺点在于,它们与其他的静态方法实际上没有任何区 别

本质上还是一个静态方法,但是实质上它用于创建对象,和普通静态方法差别很大,却没有有效的办法可以区分他们

作者的建议: 在类或接口注释中关注静态工厂,给静态工厂方法命名时遵守惯用的命名规范.

总结

简而言之,静态工厂方法和公有构造器都各有用处,我们需要理解它们各自的长处,静态工厂通常更加合适,因此切忌第一反应就是提供公有的构造器,而不先考虑静态工厂

相关文章

  • effective java读书笔记

    一、考虑用静态工厂方法代替构造器1.静态工厂方法有名称,而构造器只能是类名 private Map > map =...

  • java编程建议系列一

    1.考虑用静态工厂方法代替构造器 静态工厂方法惯用名称 valueOf —— 类型转换方法 of —— value...

  • 创建和销毁对象

    1,考虑用静态工厂方法代替构造器 切忌第一反应就是提供共有构造器,而不先考虑静态工厂。 类可以通过静态工厂方法返回...

  • 第二章 创建和销毁对象

    1.考虑用静态工厂方法代替构造器 静态工厂方法与构造器不同的优势在于: 1.他们有名称(容易阅读) 2.不用每次调...

  • effective java学习笔记 原则1:考虑用静态工厂方法

    原则1:考虑用静态工厂方法代替公有构造器 提供实例的方式:静态工厂方法(非设计模式中的静态工厂模式)公有构造器ne...

  • Java创建和销毁对象

    考虑用静态工厂方法代替构造器 静态工厂方法可以通过静态获取类的一个实例,而不需要通过构造器; 使用静态工厂方法的优...

  • Effective Java 读书笔记

    1. 创建和销毁对象 ## *1.考虑用静态工厂方法代替构造器* #### 优势 1.有名称 2.静态...

  • EffectiveJava读书笔记一

    第2章 创建和销毁对象 1. 考虑用静态工厂方法代替构造器 静态工厂相比构造器的优点来说如下: 有名称 不必每次创...

  • effecitveJava读书笔记

    1.创建与销毁对象 1.1考虑用静态工厂方法代替构造器 这里的静态工厂不是我们说设计模式中静态工厂方法模式;可以理...

  • Effective JAVA

    创建和销毁对象 1.考虑用静态工厂方法代替构造器2.遇到多个构造器参数时要考虑用构建器3.用私有构造器或者枚举类型...

网友评论

      本文标题:1.考虑用静态工厂方法代替构造器

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