Effective Java理解笔记系列-第1条-何时考虑用静态工厂方法替代构造器?
为什么写这系列博客?
在阅读《Effective Java》这本书时,我发现有许多地方需要仔细认真地慢慢阅读并且在必要时查阅相关资料才能彻底搞懂,相信有些读者在阅读此书时也有类似感受;同时,在解决疑惑的过程中,还存在着有些内容不容易查找、查找到的解答质量不高等问题,于是我决定把我阅读此书收获到的东西写成博客,期望能够解答某些读者之困惑。
为了方便大家阅读时按章节查找,我会按照原书籍写作顺序来划分博客章节。博客中主要包含以下内容:
- 我对原文内容的理解(再加工)
- 一些补充知识(需要理解这些知识才能真正理解该章节内容)
创建和销毁对象
何时考虑用静态工厂方法替代构造器?
无法准确描述
该实例无法通过构造器名称和参数完整描述。--》目的:方便用户正确调用。
BigInteger(int,int,Random) // 使用构造器
BigInteger.probablePrime(int,int,Random)//静态工厂方法
//以上构造器返回的实例可能为质数,通过构造器名称BigInteger和参数列表无法体现出质数,所以用静态工厂方法更好。
重复利用缓存
不可变类在创建实例时重复利用事先构建好或已缓存的实例。--》目的:避免创造不必要对象,降低内存提升性能;客户端可以用==操作符替代equals方法,提升性能,如:
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
public static Boolean valueOf(boolean b){
return b? Boolean.TRUE:Boolean.FALSE;//通过valueOf调用得到的某个值的实例都是一个实例,所以可以用==来比较
}
隐藏实现类
返回接口类型,隐藏实现类--》目的:客户端使用只需关注接口功能即可,而不需要关注具体实现类;可灵活替换返回对象,而客户端不需要修改代码。
隐藏实现类的方法:使用内部类
- 静态内部类:Collections类中的UnmodifiableList内部类
- 实例内部类:LinkedList类中的ListItr内部类
导出实现类的方法:
- 静态工厂导出,如:Collections类中的静态工厂方法:unmodifiableList
- 通过实例方法导出,如:LinkedList类中的实例方法:listIterator
其他补充知识:
当内存中只需要一份,没有多个实例化的需求,不需要多份时,就考虑使用静态变量和静态方法(注意保持不可实例化,私有构造函数并抛出异常),如:各种工具类(java.lang.Math);管理器类(JDBC的java.sql.DriverManager)
内部类:
使用场景:该内部类只和当前外部类(相对而言)相关,而和其他类无关,其他类不需要知晓该类的存在。
静态or实例?如果该内部类不需要使用实例域或者外部类没有实例域,用静态内部类;反之用实例内部类
方法内部类和匿名内部类如何选择?
- 这两个类都是只限定在当前方法内可用,方法外不可用
- 如果只需要创建一个对象,使用匿名内部类即可;反之,需要多次创建对象,那么使用方法内部类
匿名内部类的常见使用场景:定义比较器或者事件响应逻辑
框架开发经验:考虑哪部分是不变的固定逻辑,哪部分是开发者需要自定义的逻辑,提供一个接口让开发者实现即可。
避免繁杂类型参数
利用编译器的类型推导,避免实例化时编写繁杂的类型参数--》目的:让代码更加简洁。
//未使用静态工厂写法
Map<String,List<String>> map = new HashMap<String,List<String>>();
//工具类
public class MapUtil{
//避免实例化
private MapUtil{}
//静态工厂方法
public static <K,V> HashMap<K,V> newInstance(){
return new HashMap<K,V>();
}
}
//使用静态工厂写法
Map<String,List<String>> map = MapUtil.newIntance();
总结
提升简洁性:第四条
提高易用性:第一条;第三条前半部分
可扩展性:第三条后半部分
提升性能:第二条
Effective Java理解笔记系列-第1条-何时考虑用静态工厂方法替代构造器?的更多相关文章
- Effective java读书札记第一条之 考虑用静态工厂方法取代构造器
对于类而言,为了让client获取它自身的一个实例,最经常使用的方法就是提供一个共同拥有的构造器. 另一种放你发,也应该子每一个程序猿的工具箱中占有一席之地.类能够提供一个共同拥有的静态 工厂方法.它 ...
- Effective Java 读书笔记(一):使用静态工厂方法代替构造器
这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...
- Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- effective java 3th item1:考虑静态工厂方法代替构造器
传统的方式获取一个类的实例,是通过提供一个 public 构造器.这里有技巧,每一个程序员应该记住.一个类可以对外提供一个 public 的 静态工厂方法 ,该方法只是一个朴素的静态方法,不需要有太多 ...
- 改善JAVA代码01:考虑静态工厂方法代替构造器
前言 系列文章:[传送门] 每次开始新的一本书,我都会很开心.新书新心情. 正文 静态工厂方法代替构造器 说起这个,好多可以念叨的.做了一年多的项目,慢慢也有感触. 说起构造器 大家很明白,构造器 ...
- Java - 用静态工厂方法代替构造器
Effective Item - 考虑用静态工厂方法代替构造器我们有两种常见的方法获得一个类的实例: 公有的构造器 提供静态工厂方法(static factory method) 相对公有的构造器,静 ...
- 高效JAVA之用静态工厂方法代替构造器
程序员这行干的久了,总会染上一些恶习,我就染上一个让人深恶痛绝,自己却津津乐道的习惯,还不想改的那种,它可以叫做强迫症,也可以叫做洁癖.那就是我不允许我的IDEA出现一点点警告,什么黄色背景,绿色波浪 ...
- Effective Java —— 用静态工厂方法代替构造器
本文参考 本篇文章参考自<Effective Java>第三版第一条"Consider static factory methods instead of constructor ...
- Effective Java 学习笔记之第七条——避免使用终结(finalizer)方法
避免使用终结方法(finalizer) 终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的. 不要把finalizer当成C++中析构函数的对应物.java中,当对象不 ...
- Effective Java读书笔记——第三章 对于全部对象都通用的方法
第8条:覆盖equals时请遵守通用的约定 设计Object类的目的就是用来覆盖的,它全部的非final方法都是用来被覆盖的(equals.hashcode.clone.finalize)都有通用约定 ...
随机推荐
- React中的 ref 及原理浅析
前言 对于 ref 的理解,我们一部人还停留在用 ref 获取真实 dom 元素和获取组件层面上,但实际 ref 除了这两项功能之外,在使用上还有很多小技巧.本章我们就一起深入探讨研究一下 React ...
- ArrayList源码解析-JDK18
引言 ArrayList在JDK1.7和1.8中的差距并不大,主要差距以下几个方面: JDK1.7 在JDK1.7中,使用ArrayList list = new ArrayList()创建List集 ...
- 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-11- 标签页(tab)操作 - 下篇 (详细教程)
1.简介 本来按照计划这一系列的文章应该介绍Context和Page两个内容的,但是宏哥看了官方文档和查找资料发现其实和宏哥在Python+Playwright系列文章中的大同小异,差不了多少,再在这 ...
- 记录vue和element-ui导出表格到excell
1.安装插件 npm install 'file-saver' npm install 'xlsx' 2.引入插件 import FileSaver from 'file-saver' import ...
- 题解:CF727F Polycarp's problems
link. 贪心做法. 本题贪心做法的实质就是用整数尽量多地抵消该整数后面的负数. 如果正着做,没有办法考虑全该数后面的所有负数,所以倒着做. 例如当前遍历到了 \(50\),此时序列如下: \[\d ...
- 【java提高】---细则(1)
异常 一.异常与错误的区别 再讲异常之前我们就应该要知道异常和错误的区别 Error类和Exception类的父类都是throwable类,他们的区别是: Error类一般是指与虚拟机相关的问题,如系 ...
- C# 开发工具Visual Studio 介绍
Visual Studio Community (社区版) 这个版本的 Visual Studio 是免费的,具备以前 Professional 版的功能.使用时间有许可限制.它对开源项目和培训.学术 ...
- Java实现LDAP登录
LDAP的全称是Lightweight Directory Access Protocol(轻量级目录访问协议),是一种用于访问和管理分布式目录信息服务的应用协议.LDAP通常用于存储用户.组和其他组 ...
- 利用Python开发Exporter,集成Prometheus和Grafana对进程监控
利用Python开发Exporter,集成Prometheus和Grafana对进程监控 在现代软件开发和运维中,监控是确保系统稳定运行和快速响应问题的重要手段.Prometheus和Grafana的 ...
- SNMP简介
复习几组概念带内管理和带外管理区别:传送的物理通道不同.1.带内管理是管理控制信息与数据信息使用统一物理通道进行传送.当网络出现故障中断时数据传输和管理都无法正常进行.2.带外管理在于通过不同的物理通 ...