本文摘自:https://blog.csdn.net/wh2827991/article/details/79013115

在实例化一个类的过程中,通常会遇到多个参数的构造函数,但如果有些参数是非必需的呢?每次都要初始化那么多参数么?

public class Person {
private int id;//身份证号
private String name;//姓名
private int age;//年龄
private boolean sex;//性别
private String desc;//个人描述
public Person(int id, String name, int age, boolean sex, String desc) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
this.desc = desc;
}
}

或者像下面这样,创建一个必选参数的构造器,在创建几个可选参数的构造器?

    public Person(int id, String name) {//两个参数的
this.id = id;
this.name = name;
} public Person(int id, String name, int age) {//三个参数的
this.id = id;
this.name = name;
this.age = age;
} public Person(int id, String name, int age, boolean sex) {//四个参数的
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}

或setter方法?

JavaBean模式自身有严重的缺点,因为构造过程被分到几个调用中,在构造过程中Javabean可能处于不一致的状态,类无法仅仅通过检验构造器参数的有效性来保证一致性。JavaBean模式阻止了把类做成不可变的可能,这就需要程序员付出额外的努力确保线程安全 ---摘自Effective Java

那么我们该怎样用构建器来实现类的实例化而又不受制于构造函数限制呢?

public class Person {
private final int id;//身份证号
private final String name;//姓名
private int age;//年龄
private boolean sex;//性别
private String desc;//个人描述
private Person(Builder builder){
this.id=builder.id;
this.name=builder.name;
this.age=builder.age;
this.sex=builder.sex;
this.desc=builder.desc;
}
public static class Builder{
private final int id;
private final String name;
private int age;
private boolean sex;
private String desc;
public Builder(int id, String name) {
this.id = id;
this.name = name;
}
public Builder age(int age){
//年龄合法性检查
if(age<0)throw new IllegalArgumentException();
else this.age=age;
return this;
}
public Builder sex(boolean sex){
this.sex=sex;
return this;
}
public Builder desc(String desc){
this.desc=desc;
return this;
}
public Person build(){
return new Person(this);
}
} @Override
public String toString() {
return "id:"+this.id+" 姓名:"+this.name+" 年龄:"+this.age+" 性别:"+this.sex+" 描述:"+this.desc;
}
}

我们在main函数中测试一下

    public static void main(String[] args) {
Builder builder=new Person.Builder(123,"张三");
Person person=builder.age(18).sex(false).desc("好好学习,天天向上").build();
System.out.println(person.toString());
}

用构建器创建的实例易于阅读和编写,较javaBean模式又更加安全,自然,每种方法都会有其优点和弊端,选择合适的使用场景,会让代码更加健壮易读。

java构造器和构建器的更多相关文章

  1. Java构造器与构建器的使用

    我们在平常类的构建过程中,可能会面临很多问题,可扩张性.安全性等等.想象一下,这样一个场景,我们现在要创建一个类,其中有6个属性,其中又有4个属性的值是不太确定的(可能某个对象就不需要其中的某个值), ...

  2. 深入探索Java设计模式之构建器模式(五)

    抽丝剥茧 细说架构那些事——[优锐课] 简单的程序不需要大量的设计过程,因为它们只关注有限的解决方案,仅使用几个类.大型程序专注于广泛的设计,该设计比好的设计范例的任何其他属性都更能利用可重用性.宏伟 ...

  3. Java基础——字符串构建器

    StringBuilder类: 可以将许多小段的字符串构建一个字符串. StringBuilder builder = new StringBuilder(); //构造一个空的字符串构建器 buil ...

  4. effective java之使用构建器来创建对象

    第二章第2条:遇到多个构造器参数时要考虑使用构建器(builder) 就是建造者模式(不直接生成想要的对象,而是让客户端利用所有有必要的参数调用构造器或者静态工厂)直接上代码 package com. ...

  5. 【转】通过lombok带你读透Builder构建器

    原地址:https://www.jianshu.com/p/0d8fc3df3647?from=timeline&isappinstalled=0 很久之前,我在<effective j ...

  6. Java 构造器 遇到多个构造器时要考虑用构建器

    静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数. 当一个类中有若干个必选属性和多个可选属性时,采用重叠构造器模式.JavaBeans模式或者Builder模式,但各有优劣. 当 ...

  7. 【读书笔记 - Effective Java】02. 遇到多个构造器参数时要考虑用构建器

    类有多个可选参数的解决方案: 1. 重叠构造器模式可行,但是当有许多参数的时候,客户端代码会很难编写,并且仍然较难以阅读. 2. JavaBeans模式,调用一个无参构造器来创造对象,然后调用sett ...

  8. Java构建器(多个构造器参数)

    今天看netty权威指南,第一次听说构建器,百度了几个博客,但是并没有通俗易懂一点儿的,综合别人的博客,总结如下: 1. 构建器是什么? 当创建对象需要传入多个参数的时候我们通常会根据参数的数量写不同 ...

  9. Effective JAVA 创建和销毁对象 遇到多参构造器考虑使用构建器

    //构建器抽象类,为不同类的实现提供 public interface Builder<T> { public T build(); } /** * @描述: 营养表 */ public ...

随机推荐

  1. 004_Python之all()\any()

    http://www.jianshu.com/p/65b6b4a62071 一.待验证整理

  2. ubuntu1604安装谷歌游览器

    https://www.linuxidc.com/Linux/2016-05/131097.htm 在终端中依次运行如下命令: sudo add-apt-repository ppa:a-v-shko ...

  3. ROS 创建服务和请求

    教程 维基 http://wiki.ros.org/cn/ROS/Tutorials 快速过程 创建包 $ cd ~/catkin_ws $ mkdir ~/catkin_ws/src $ cd ~/ ...

  4. i春秋-百度杯十月场-fuzzing

    1. 打开链接,提示 show me key,抓包,传值key=1,GET请求没有用,而POST请求有返回. 2.将md5值直接拿去解密,得到key=ichunqiu105    OK,进入下一步. ...

  5. nginx指定配置文件启动

    /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

  6. SimpleDialogBox

    import 'package:flutter/material.dart';import 'dart:ui';import 'dart:async';enum Option{A,B,C}void m ...

  7. Scala学习(九)练习

    文件正则表达式&练习 1. 编写一小段Scala代码,将某个文件中的行倒转顺序,将最后一行作为第一行,依此类推 程序代码: import scala.io.Source import java ...

  8. 蓝牙LMP概述

    LMP 全称是Link Manager Protocol,我们还是要一张图,说明LMP 在哪里? 他是在HCI 以下,baseband 以上,实现在蓝牙控制器中. 按照协议规范,我们分几个部分来分别介 ...

  9. Apache Spark 内存管理详解(转载)

    Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...

  10. NLog配置分享

    新建一个文件命名为NLog.Config,然后添加如下代码 <?xml version="1.0" encoding="utf-8" ?> < ...