创建和销毁对象——用静态工厂方法代替构造器

  • 2019-10-30
  • 255
  • 0

静态工厂方法与构造器的差异

  • 构造器顾名思义就是类的构造方法,名称和类名相同。通过new方法实例化对象,实际上调用的就是类的构造方法。
  • 静态工厂方法就是一个返回类的实例的静态方法。例如Boolean类中的valueOf方法
    /**
     * Returns a {@code Boolean} instance representing the specified
     * {@code boolean} value.  If the specified {@code boolean} value
     * is {@code true}, this method returns {@code Boolean.TRUE};
     * if it is {@code false}, this method returns {@code Boolean.FALSE}.
     * If a new {@code Boolean} instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Boolean(boolean)}, as this method is likely to yield
     * significantly better space and time performance.
     *
     * @param  b a boolean value.
     * @return a {@code Boolean} instance representing {@code b}.
     * @since  1.4
     */
    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

静态工厂方法相比构造方法的优势在哪里

  • 静态工厂方法可以自定义为有语义的名称。而构造方法名只能和类名保持一致。
  • 不必在每次调用它们的时候都创建一个新对象。这是的不可变类可以使用预先构建好的实例,或者将构建好的实例缓存起来,进行重复利用,从而避免创建不必要的重复。相当于Java设计模式中的单例模式。
  • 它们可以返回原类型的任何子类型的对象。特别在API中可以返回对象,同时又不会使对象的类编程公有的,屏蔽了底层的实现细节
List list= Collections.synchronizedList(new ArrayList<>())
  • 所返回的对象的类可以随着每次调用而发生变化,这取决于静态工厂方法的参数值。只要是已生命的返回类型的子类型,都是允许的。返回对象的类也可以随着发行版本的不同而不同。
  • 方法返回的对象所属的类,在编写包含该静态工厂的类时可以不存在。例如JDBC的实现

静态工厂方法的缺点

  • 类如果不含公有的或者受保护的构造器,就不能被子类化,
  • 查找比较麻烦,在API文档中,它们没有像构造器那么样在API文档中明确标识出来,因此对于提供了静态工厂方法而不是构造器的类来说,要想查明如何实例化一个类是非常困难的

常见使用举例

  • from-类型转换方法,它只有单个参数,返回该类型的一个相对应的实例,例如:
Date d=Date.from(instant)
  • of-聚合方法,带有多个参数,返回该类型的一个实例,把它们合并起来,例如:
Set<Rank> faceCards=EnumSet.of(JACK,QUEEN,KING);
  • valueOf-比from和of更返货的一种替代方法
BigInteger prime=BigInteger.valueOf(Integer.MAX_VALUE);
  • instance或getInstance——返回的实例是通过方法的(如有)参数来描述的,但是不能说与参数具有同样的值
StackWalker luke=StackWalker.getInstance(options);
  • create或者newInstance——和instance或getInstance一样,但create或者newInstance能够确保每次调用都返回一个新的实例。
Object newArray=Array.newInstance(classObject,ArrayLen);
  • getType——像getInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型。
FileStore fs=Files.getFileStore(path);
  • newType——想newInstance一样,但是在工厂方法处于不同的类中的时候使用,Type表示工厂方法所返回的对象类型。
BufferedReader br=Files.newBufferedReader(path);
  • type——getType和newTYpe的简版,例如
List<Complaint> litany=Collections.list(legacyLitany);
感谢打赏!
微信

评论

还没有任何评论,你来说两句吧