今天看netty权威指南,第一次听说构建器,百度了几个博客,但是并没有通俗易懂一点儿的,综合别人的博客,总结如下:

1. 构建器是什么?

当创建对象需要传入多个参数的时候我们通常会根据参数的数量写不同的构造器,具体如下

public A(int a){}

public A(int a, int b){}

public A(int a, int b, int c){}

根据不同的参数调用不同的构造器,但是当参数多了的时候,这种方式不够灵活,所以会实现动态传参的方法

public A(){}

public void seta(int a){}

public void setb(int b){}

public void setc(int c){}

这种方式提高了传参的可读性,也提高了传参的灵活性,但是会增加代码行数,同时在多线程异步执行的时候导致奇怪的错误。

有没有办法解决呢?既能提高代码可读性,提高参数灵活性,又不会增加代码行数,并保证线程安全呢?

构建器模式登场,先看代码。

这里我们写一个 Person 类,并为这个类加上构建器:

public class Person {

private final String name;

private final int age;

private final String address;

private final String phone;

public static class Builder{

private final String name;

private final int age;

private String address = null;

private String phone = null;

public Builder(String name,int age){

this.name = name;

this.age = age;

}

public Builder address(String val){

address = val;

return this;

}

public Builder phone(String val){

phone = val;

return this;

}

public Person builder(){

return new Person(this);

}

}

private Person(Builder builder){

this.name = builder.name;

this.age = builder.age;

this.address = builder.address;

this.phone = builder.phone;

}

@Override

public String toString() {

return "name:"+name+" age:"+age+" address:"+address+" phone:"+phone;

}

}

调用这个构建器的方式

public class PersonTest {

public static void main(String[] args) {

Person p = new Person.Builder("tom", 18).address("深圳").phone("110").builder();

System.out.println(p.toString());

}

}

2. 为什么使用构建器?

2.1 参数的限制

静态工厂方法与构造器都有一个共同的局限性,就是它们不能很好的扩展到大量的可选参数。就像我们上面的那个Person 类,在实际中我们会有许多的属性,性别、出生年月、爱好...对与这样的类。

2.2 重叠构造器

我们初学的时候都会选择 重叠构造器(telecoping constructor)模式 。在这种情况下,第一个构造器是实例化对象必须的参数,第二个会多一个参数,就这样叠加,最后是一个有所有参数的构造器

public class Person {

private final String name;

private final int age;

private final String address;

private final String phone;

public Person(String name, int age) {

this(name,age,null);

}

public Person(String name, int age, String address) {

this(name,age,address,null);

}

public Person(String name, int age, String address, String phone) {

super();

this.name = name;

this.age = age;

this.address = address;

this.phone = phone;

}

@Override

public String toString() {

return "name:"+name+" age:"+age+" address:"+address+" phone:"+phone;

}

}

获得对象

public class PersonTest {

public static void main(String[] args) {

Person p = new Person("tom",18,null,"110");

System.out.println(p.toString());

}

}

在这个构造器中也许会有你不想要的参数,如果我们的参数变多了的话,情况就不会很好。

总结一句话:重叠构造器可行,但当有很多的参数的时候,客户端的代码就会很难编写并且不容易阅读我们在使用的时候,必须很仔细的看每一个参数的位置和含义。

2.3 JavaBeans模式

2.3.1 创建JavaBeans模式

这个时候我们还有一种替代的方式,这个就是JavaBeans模式。这种模式下,使用无参的构造方法创建对象,然后调用setter 方法给属性设置值

public class Person {

private String name;

private int age;

private String address;

private String phone;

public void setName(String name) {

this.name = name;

}

public void setAge(int age) {

this.age = age;

}

public void setAddress(String address) {

this.address = address;

}

public void setPhone(String phone) {

this.phone = phone;

}

@Override

public String toString() {

return "name:"+name+" age:"+age+" address:"+address+" phone:"+phone;

}

}

使用的方式,这个相比与重叠构造器更容易的创建了对象,同时让代码跟容易的阅读。

public class PersonTest {

public static void main(String[] args) {

Person p = new Person();

p.setName("tom");

p.setAge(18);

p.setAddress("深圳");

p.setPhone("110");

System.out.println(p.toString());

}

}

2.3.2 JavaBeans模式的劣势

构造的过程分到了几个调用中,在构造JavaBeans的时候可能会不一致

类无法仅仅通过检验构造器参数的有效性来保证一致性!

对象的不一致会导致失败,JavaBeans模式阻止了把类做为不可变的可能,需要程序员做额外努力来保证它线程安全。

2.4 构建器

构建器的创建对象就比较易于创建与阅读,线程安全

等待所有的参数验证通过才会build()对象。

与构造器相比,builder 的微略优势在于,builder可以有多个可变(varargs)参数。构造器像方法一样,只有一个可变参数。因为builder利用单独的方法来设置每个参数,你想要多少个可变参数,他们就可以有多少个,知道每个setter方法都有一个可变参数。

builder模式非常灵活,可以理由单个builder构建多个对象。builder的参数可以在创建对象时进行调整

设置了参数的builder生成一个很好的抽象工厂(Abstract Factory),也就是客户端可以将这样一个builder传给方法,使该方法能为客户端创建一个或者多个对象

builder也有自己的不足,就是创建对象就必须创建它的构建器。

builder模式还比重叠构造器模式更加的冗长,因此它会在参数多的时候使用。但是我们要知道,我们可能会在设计之后还要添加参数,所以一开始就用构建器还是比较好的。

3 总结

如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是不错的选择,特别是当大多数14:39:30参数都是可选的时候。

与重叠构造器相比,builder牧师的客户端更易与阅读和编写

与JavaBeans相比,更加的安全

java多个构造方法_Java构建器(多个构造器参数)相关推荐

  1. python kotlin_用Java和Python模仿Kotlin构建器

    python kotlin 介绍 Kotlin可能现在是我最喜欢的语言,可能它提供的最酷的功能之一是基于几个功能构建的类型安全的生成器(稍后解释). 我发现自己真的很想在其他两种主要语言(Java和P ...

  2. 用Java和Python模仿Kotlin构建器

    介绍 Kotlin可能现在是我最喜欢的语言,并且它可能提供的最酷的功能之一是基于几个功能构建的类型安全的生成器(稍后解释). 我发现自己真的很想在其他两种主要语言(Java和Python)中使用此功能 ...

  3. java 类复制构造方法_java面向对象入门(3)-java构造方法

    Java构造函数是特殊的方法(没有返回类型),使您可以在应用程序内部的其他类使用对象之前完全初始化对象状态.Java中的构造方法是使用new关键字调用的. 下面让我们更深入地了解构造函数. 1.什么是 ...

  4. effective java 3th item2:考虑 builder 模式,当构造器参数过多的时候

    yiaz 读书笔记,翻译于 effective java 3th 英文版,可能有些地方有错误.欢迎指正. 静态工厂方法和构造器都有一个限制:当有许多参数的时候,它们不能很好的扩展. 比如试想下如下场景 ...

  5. java 类加载 双亲委派_Java类加载器和双亲委派机制

    前言 之前详细介绍了Java类的整个加载过程(类加载机制详解).虽然,篇幅较长,但是也不要被内容吓到了,其实每个阶段都可以用一句话来概括. 1)加载:查找并加载类的二进制字节流数据. 2)验证:保证被 ...

  6. java log4j 热部署_JAVA类加载器分析--热部署的缺陷(有代码示例,及分析)

    首先纠正一个误区: 热部署不是我们在Eclipse里面修改了代码不用重启就可以持续调试. 详情可以参考上一篇博文: 热部署和"Hot Code Replace"的区别    htt ...

  7. java中面积构造方法_JAVA图形面积与周长(抽象类)

    /*面向对象具有抽象性.封装性.继承性.多态性.抽象性是将具有一致的数据结构(属性)和行为(操作)的对象抽象成类 一个类就是一种抽象.封装性体现在Java中的数据除了基本类型的数据外,都以对象的形式存 ...

  8. java 匿名类 构造方法_Java中接口式的匿名内部类的构造方法

    在使用多线程的时候,时常会使用两种方式实现,一种是直接继承Thread类来实现多线程,另外一种就是实现Runnable接口. 我们都知道,接口是没有构造方法的,同时匿名内部类也是没有构造方法的.原因有 ...

  9. java 类加载 双亲委派_java类加载器和双亲委派模型

    一. 类加载器 ClassLoader即常说的类加载器,其功能是用于从Class文件加载所需的类,主要场景用于热部署.代码热替换等场景. 系统提供3种的类加载器:Bootstrap ClassLoad ...

最新文章

  1. HDUOJ-----Brave Game
  2. 《Spring Cloud微服务架构开发实战》_董超笔记
  3. Spring JdbcTemplate配置
  4. 日志库 winston 的学习笔记 - 创建一个使用 winston 的 Node.js 应用
  5. matlab提取图像中的一部分并移动,在Matlab中从图像中提取对象
  6. 如何将多个文本数据转化为指定数据格式[以电影数据为例](数据预处理)
  7. 数据型驱动风控有什么内容?从蚂蚁借呗与花呗谈起~
  8. Linux 高性能服务器编程——多进程编程
  9. 世界500强面试题(经典)
  10. unity3d棋牌游戏教程之手机斗地主的发牌功能实现
  11. Linux、Qt等安装镜像下载--清华大学开源软件镜像站
  12. 【ubuntu操作系统入门】系统输入法设置
  13. 计算机在智能建筑中的应用,【计算机技术在建筑智能化中的应用研究原稿_0材料】...
  14. 关于STM32 程序烧录不进去
  15. 人脸识别中的活体检测算法综述
  16. Android多点触控揭秘
  17. 侍魂哪个服务器人最多,为什么那么多人喜欢侍魂2,而我却觉得侍魂5比2好玩多了?...
  18. 倍福PLC和C#通过ADS通信传输Bool数组变量
  19. r5 5600u和r5 4600u参数对比哪个好?
  20. matlab旁瓣干扰,相控阵雷达波束形成与旁瓣干扰抑制研究

热门文章

  1. 【运维小工具】 - Mac OS 如何查看cpu支持的指令集?
  2. mysql编写存储过程给员工加工资_一个增加员工工资的数据库存储过程
  3. 10月笔试面试记录分享
  4. 免费分享价值20多万9大编程教学视频
  5. coreldraw x7 分布_使用CorelDRAW X7软件排版三大实用功能
  6. coreldraw x7怎样设置禁网_怎样设置文件禁止访问网络
  7. 辐射亮度与表观反射率的转换
  8. 微信公众号配置自定义菜单跳转小程序,自动回复跳转小程序
  9. dos重启计算机命令行,命令行中,重启计算机的命令是什么
  10. 初识西门子Wincc OA——超大型/分布式SCADA