java构造器和构建器
本文摘自: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构造器和构建器的更多相关文章
- Java构造器与构建器的使用
我们在平常类的构建过程中,可能会面临很多问题,可扩张性.安全性等等.想象一下,这样一个场景,我们现在要创建一个类,其中有6个属性,其中又有4个属性的值是不太确定的(可能某个对象就不需要其中的某个值), ...
- 深入探索Java设计模式之构建器模式(五)
抽丝剥茧 细说架构那些事——[优锐课] 简单的程序不需要大量的设计过程,因为它们只关注有限的解决方案,仅使用几个类.大型程序专注于广泛的设计,该设计比好的设计范例的任何其他属性都更能利用可重用性.宏伟 ...
- Java基础——字符串构建器
StringBuilder类: 可以将许多小段的字符串构建一个字符串. StringBuilder builder = new StringBuilder(); //构造一个空的字符串构建器 buil ...
- effective java之使用构建器来创建对象
第二章第2条:遇到多个构造器参数时要考虑使用构建器(builder) 就是建造者模式(不直接生成想要的对象,而是让客户端利用所有有必要的参数调用构造器或者静态工厂)直接上代码 package com. ...
- 【转】通过lombok带你读透Builder构建器
原地址:https://www.jianshu.com/p/0d8fc3df3647?from=timeline&isappinstalled=0 很久之前,我在<effective j ...
- Java 构造器 遇到多个构造器时要考虑用构建器
静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数. 当一个类中有若干个必选属性和多个可选属性时,采用重叠构造器模式.JavaBeans模式或者Builder模式,但各有优劣. 当 ...
- 【读书笔记 - Effective Java】02. 遇到多个构造器参数时要考虑用构建器
类有多个可选参数的解决方案: 1. 重叠构造器模式可行,但是当有许多参数的时候,客户端代码会很难编写,并且仍然较难以阅读. 2. JavaBeans模式,调用一个无参构造器来创造对象,然后调用sett ...
- Java构建器(多个构造器参数)
今天看netty权威指南,第一次听说构建器,百度了几个博客,但是并没有通俗易懂一点儿的,综合别人的博客,总结如下: 1. 构建器是什么? 当创建对象需要传入多个参数的时候我们通常会根据参数的数量写不同 ...
- Effective JAVA 创建和销毁对象 遇到多参构造器考虑使用构建器
//构建器抽象类,为不同类的实现提供 public interface Builder<T> { public T build(); } /** * @描述: 营养表 */ public ...
随机推荐
- 【移动端】移动端字体单位font-size选择px还是rem
对于只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可对于需要适配各种移动设备,使用rem,例如只需要适配iphone和iPad等分辨率差别比较挺大的设备 html{font-size: ...
- java 生成txt文件
FileWriter fileWriter = new FileWriter("C:/Users/li/Desktop/a.txt"); fileWriter.write(“aaa ...
- wordpress数据表分析
wordpress一共是有12个表的:|wp_commentmeta || wp_comments || wp_links || wp_options || wp_postmeta || wp_pos ...
- 线程的synchronized、volatile及原子操作
public class ThreadDemo7{ //structs2线程不安全 共享变量 //n++ 复合操作 对于volatile修饰的变量不安全 //原子操作 int value; //让方法 ...
- PHP创建socket服务
PHP可以创建socket服务. 先熟悉几个php网络方面的函数,操作手册地址 http://php.net/manual/zh/ref.sockets.php 简单介绍下socket,它表示套接字 ...
- C# 多线程及同步简介示例
60年代,在OS中能拥有资源和独立运行的基本单位是进程,然而随着计算机技术的发展,进程出现了很多弊端,一是由于进程是资源拥有者,创建.撤消与切换存在较大的时空开销,因此需要引入轻型进程: ...
- [Spark][Flume]Flume 启动例子
Flume 启动例子: flume-ng agent --conf /etc/flume-ng/conf --conf-file /etc/flume-ng/conf/flume.conf --nam ...
- 解决在ubuntu上启动的django项目在windows进行访问无法访问的问题
windows想要访问VMware中Ubuntu Server中Debug模式下的django服务,需要设置django允许非本机ip访问. 设置方法:1.查看虚拟机ip(建议VMware中设置Ubu ...
- 升级MySQL5.7,开发不得不注意的坑
前段时间,将线上MySQL数据库升级到了5.7.考虑到可能产生的不兼容性,在升级之前,确实也是战战兢兢,虽然测试环境,开发环境早在半年前就已提前升级. 基于前期的调研和朋友的反馈,与开发相关的主要有两 ...
- Tarjan算法(缩点)
因为最近在学2sat,需要学习前置技能—Tarjan算法,所以花了一天的时间学习这个算法 算法步骤: 1.从一个点开始dfs,并加入栈 2.如果下一个点没有到过,跳到第一步 3.如果下一个点到过,并且 ...