Java构造器与构建器的使用
我们在平常类的构建过程中,可能会面临很多问题,可扩张性、安全性等等。想象一下,这样一个场景,我们现在要创建一个类,其中有6个属性,其中又有4个属性的值是不太确定的(可能某个对象就不需要其中的某个值),这时我们怎么创建这个类呢?以下是几种方法:
使用普通构造器
public class Test {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate; public Test(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = 0;
} public Test(int servingSize, int servings, int calories) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = 0;
} public Test(int servingSize, int servings, int calories, int fat) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = 0;
} public Test(int servingSize, int servings, int calories, int fat, int sodium) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = 0;
} public Test(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
} }
我们完成该类构建后,接下来就是调用的过程:
public static void main(String[] args) {
Test test = new Test(1,2,3,0,5,6);
}
如上所示,在实例化对象时,我们需要传入相应的值,这时发现:
- 第四个参数不是我们需要的,但是还不得不给他传递一个值
- 我们在传值时,很容易出错,某两个参数值互换了位置,这在工作时是不好发现的,但是程序会报错
所以上面的方式在涉及到参数比较多,而且参数值不太确定是否需要时,这种方法会给我们的编码以及后期维护带来很大的困扰,我们再改进一下。
JavaBeans模式
public class Test {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate; public Test() { } public void setServingSize(int servingSize) {
this.servingSize = servingSize;
} public void setServings(int servings) {
this.servings = servings;
} public void setCalories(int calories) {
this.calories = calories;
} public void setFat(int fat) {
this.fat = fat;
} public void setSodium(int sodium) {
this.sodium = sodium;
} public void setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
} }
如上,我们先创建一个无参构造方法(可以不写出来,会默认创建),接下来就是利用setter方法给属性赋值
public static void main(String[] args) {
Test test = new Test();
test.setServingSize(1);
test.setCalories(2);
test.setCalories(3);
test.setSodium(5);
test.setCarbohydrate(6);
}
如上,我们需要的对象不需要fat属性,我们就不用给其赋值,这中方法有几个好处:
- 客户端调用简单,也就是实例化对象的过程十分简单,并且不会出现把值传递出错的风险
- 别人能够很好的使用且理解简单
但是我们知道,javaBeans有个缺点:
- 线程不安全,因为对象的创建分在了好几步的过程中,不能保证对象状态的一致性
我们可以确保线程的安全,这就需要我们额外的精力(我们可以在对象构造完成,并且不允许在冻结之前使用时,手动冻结,实际中很少使用,编译器无法确定我们是否调用的freeze方法
)。因此这种方法也不够理想,还有什么继续改进的地方吗?
构建器(建造者模式的一种形式)
public class Test {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate; public static class Builder {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate; public Builder (int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
} public Builder calories(int calories) {
calories = calories;
return this;
} public Builder fat(int fat) {
fat = fat;
return this;
} public Builder sodium(int sodium) {
sodium = sodium;
return this;
} public Builder carbohydrate(int carbohydrate) {
carbohydrate = carbohydrate;
return this;
} public Test builder () {
return new Test(this);
}
} private Test(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
调用方式:
public static void main(String[] args) {
Test test = new Builder(1,2).calories(3).fat(4).sodium(5).carbohydrate(6).builder();
}
这样就保证了对象在不变的情况下,简单明了地实现了对象实例化(至于代码中的内部类,我们以后细说)。
Java构造器与构建器的使用的更多相关文章
- java构造器和构建器
本文摘自:https://blog.csdn.net/wh2827991/article/details/79013115 在实例化一个类的过程中,通常会遇到多个参数的构造函数,但如果有些参数是非必需 ...
- 深入探索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 ...
随机推荐
- kubernetes in action - Pods
Pods 在上一篇也说明了,pods是kubernetes的最小部署单元,并且所有在pods中的container共享namespaces 那么为什么需要pods这样的概念? 因为在实际中,我们有一种 ...
- git使用:本地分支merge到远程分支
背景:为了更加规范维护自动化测试工程,代码提交流程最近更新了,先拉分支到本地修改,完成后同步到远程分支. 前置条件 (1)本地机器可通过ssh与gitlab服务器通信 (2)gitlab上的测试项目中 ...
- opencart3调用三级菜单level 3 sub categories
Opencart 3的menu菜单默认只调用一级和二级菜单,但很多电商网站类目复杂,三级菜单一般都是需要的,甚至更深,那么如何调用三级菜单level 3 sub categories呢?ytkah有一 ...
- 一、初识CocoaPods——XCode的依赖库管理工具
概述 任意一款功能完整的APP,其中所涉及的内容都将是来自各个领域各个方面的.如果每个领域的每个方面都要重新开发并给予充分测试,那么1个APP的开发周期将会变得非常漫长,长到足以让房价再涨一倍,长到足 ...
- 一个农民工混迹于 IT 行业多年后的泣血总结
一看题目,你心里一定闪出一个想法,这又是一篇软文吧,是不是,不想辩别了,自己判断吧哈哈.这是根据本人真实经历所写的一篇总结.假如你满足你的现状,这就是一篇软文,请立刻关闭此文章,继续你现在的生活. ...
- 短信利用weixin://connectToFreeWifi/?apKey=协议跳转到微信打开落地页h5
微信门店wifi接口,任意站跳转,跳转二维码长按识别加粉,接口支持动态传参数,支持微信支付等特殊接口对接. 代码如下使用 <head> <meta charset="utf ...
- java实现栈的简单操作
public class stract { public static void main(String[] args) { MyStack stack = new MyStack(20); stac ...
- 【论文速读】Fangfang Wang_CVPR2018_Geometry-Aware Scene Text Detection With Instance Transformation Network
Han Hu--[ICCV2017]WordSup_Exploiting Word Annotations for Character based Text Detection 作者和代码 caffe ...
- 已有的PHP安装gd扩展
第一步 安装依赖 1.安装xpm yum install libXpm-devel 2.安装zlib wget http://zlib.net/zlib-1.2.8.tar.gz tar -xzvf ...
- Redis做分布式锁
在分布式系统中,在接口没有保证幂等性或者在某些场景下相同的服务需要有且仅有一个服务执行的情况下,需要使用分布式锁来保证系统的安全执行. 分布式锁的执行顺序,有服务A,分别部署了三个节点为A1.A2.A ...