java利用构建器来创建实例而不是构造器

Posted 网管布吉岛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java利用构建器来创建实例而不是构造器相关的知识,希望对你有一定的参考价值。

  java利用构建器来创建实例而不是构造器

  1、对于类而言,为了让客户端获取他本身的一个实例,

  2、最传统的方法就是提供一个公有的构造器。

  一个类中

  重载多个构造器

  客户面对多个构造器这种API永远也记不住该用哪个构造器,

  并且每次调用构造器必然会创建新的对象,

  如果程序需要重复使用对象,构造器无法避免创建不必要的对象。

  静态工厂方法与构造器不同的

  第一大优势为:他们有名称

  第二大优势为:不必每一次调用他们的时候创建一个新对象

  第三大优势为:他们可以返回原返回类型的任何子类型的对象

  第四大优势为:所返回的对象的类随着每次调用发生变化,这取决于静态方法的参数值

  下面是静态工厂方法的一些惯用名称

  1)from---------------------类型转换方法

  Date d = Date.from(instant)

  2)of------------------------聚合方法,带有多个参数,返回该类型的一个实例,把他们合并起来

  Set faceCard = EnumSet.of(JACK,QUEEN,KING)

  3)valueOf-----------------比前两个更繁琐的方法BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE)

  …

  一个构造器中有多个参数时

  静态工厂和构造器有个共同的局限性:

  他们都不能很好的扩展到大量的可选参数。

  比如用一个类来表示食品外面的营养成分标签。

  构造器调用了通常你不想设置的参数,

  仅仅是几个参数还可接受,但随着参数的增加,很快就失去了控制。

  简而言之,重叠构造器模式可行,但当有更多的参数是,客户端的代码会看起来非常糟糕。

  javaBean看起来强于上述的重叠构造器模式,但同时也会带来多线程下不安全的问题

  那么,我们的构建器出场了。

  利用静态内部类Builder,定义与外部类的成员完全相同的成员变量。

  类似于javaBean的模式设置每一个参数

  最后用build方法构建外部类的新实例(调用外部类的私有构造器)

  Main.java

  public class Main

  {

  public static void main(String[] args)

  {

  //初始化一个NutritionFacts实例,一定要最后调用build()方法去调用NutritionFacts类的构造器去实例化NutritionFacts的对象

  NutritionFacts cocaCola = new NutritionFacts.Builder(120,200).calories(1).carbohydrate(22).build();

  //并且参数由客户端调用时决定,并不是一定要固定输入参数,改进写重载很多构造器给用户带来麻烦

  //javaBean改进了重载一大堆构造器的问题,却也带来了线程不安全的问题

  NutritionFacts cocaCola1 = new NutritionFacts.Builder(223,233).build();

  }郑州人流专科医院 http://www.03912316666.com/

  }

  NutritionFacts.java

  public class NutritionFacts

  {

  private final int servingSize;

  private final int servings;

  private final int calories;

  private final int fat;

  private final int sodium;

  private final int carbohydrate;

  //私有构造器方法

  private NutritionFacts(Builder build)

  {

  this.servingSize=build.servingSize;

  this.servings=build.servings;

  this.calories=build.calories;

  this.fat=build.fat;

  this.sodium=build.sodium;

  this.carbohydrate=build.carbohydrate;

  }

  //构建者模式(Builder为静态内部类)可由外部直接访问

  public static class Builder

  {

  private final int servingSize;

  private final int servings;

  //初始化默认值

  private int calories=0;

  private int fat=0;

  private int sodium=0;

  private int carbohydrate=0;

  //构造器用于初始化不可变(final)参数

  public Builder(int servingSize,int servings)

  {

  this.servingSize=servingSize;

  this.servings=servings;

  }

  //以下的方法均用于初始化每一个成员

  public Builder calories(int calories)

  {

  this.calories=calories;

  return this;

  }

  public Builder fat(int fat)

  {

  this.fat=fat;

  return this;

  }

  public Builder sodium(int sodium)

  {

  this.sodium=sodium;

  return this;

  }

  public Builder carbohydrate(int carbohydrate)

  {

  this.carbohydrate=carbohydrate;

  return this;

  }

  //最后构造NutritionFacts类的实例,该方法定义于Builder类中

  public NutritionFacts build()

  {

  return new NutritionFacts(this);

  }

  }

  }

以上是关于java利用构建器来创建实例而不是构造器的主要内容,如果未能解决你的问题,请参考以下文章

面试系列——Retrofit 框架分析使用总结

java-对象的创建

面试系列——Retrofit 框架分析使用总结

java中构造方法和拷贝构造方法是啥意思

Effective Java 学习笔记之创建和销毁对象

java创建一个子类对象是会调用父类的构造方法会不会创建父类