EffectiveJava 学习总结(一)
来源:互联网 发布:c语言游戏程序代码 编辑:程序博客网 时间:2024/06/05 03:25
一、创建和销毁对象
1、考虑用静态工厂方法代替构造器
- 优点
- 有名称,易于管理和理解
- 不必每次都创建一个新对象
- 可以返回任何子类型的对象
- 例如写服务端接口,根据用户的参数init不同的service存入Map,key就是用户参数,需要哪个业务就用那个service
- 参数实例化的时候使代码变得更加简介
- new hashMap< String, Object>();如果静态工厂方法通过泛型返回这个,就不用写这么多了。现在好像也不用非要指明了,这是一种思想
- 缺点
- 最主要的是必须要有构造器,否则不能被子类化(不能被继承)
- 与一般的静态方法实际上没有任何区别,这个就需要约定
- 代码见下载包的chapter02-item01,下载地址:effective java中文第2版示例代码
2、遇到多个构造器参数时要考虑用构建器
- 其他常用方法的缺点
- 普通构造器,参数多了的话各种组合麻烦不说,而且名称都一样,只能通过传递的参数来判断是什么逻辑
- javaben模式,set的话挺直观,但是有严重的缺点,构造被分到了几个调用中,不一定能保证javabean处于一致的状态,需要保证线程安全
- 构建器(Builder)
- 优点
- 又有安全性,又有可读性,编写也容易
- 缺点
- 实例化对象的时候需要先创建构造器
- 参数少的时候有些冗余
- 描述
- 让用户利用所有必要的参数调用构造器(或静态工厂),得到一个builder对象,然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数,最后客户端调用无参的build方法来生成不可变的对象
- 内部类实现,类似于mybatis generator生成的bean
- 代码
- 优点
public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate; // 构造方法 private NutritionFacts(Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } // 构建器 public static class Builder { private final int servingSize; private final int servings; private int calories = 0; private int fat = 0; private int carbohydrate = 0; private int sodium = 0; // 构建器的构造方法 public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } public Builder fat(int val) { fat = val; return this; } public Builder carbohydrate(int val) { carbohydrate = val; return this; } public Builder sodium(int val) { sodium = val; return this; } public NutritionFacts build() { // 把构架器Build传入NutritionFacts类的构造方法 return new NutritionFacts(this); } } // 测试 public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8) .calories(100).sodium(35).carbohydrate(27).build(); } }
3、用私有构造器或者枚举类型强化Singleton属性
- 单例模式的一般实现
- 模式看了一篇文章: 单例模式的七种写法
- 本书的作者推荐使用枚举类型,并且称为实现Singleton的最佳方法
- 更加简洁
- 无偿提供了序列化机制
- 绝对防止多次实例化
- 防止反射攻击
- 代码
public enum Elvis { INSTANCE; public void leaveTheBuilding() { System.out.println("Whoa baby, I'm outta here!"); } public static void main(String[] args) { Elvis elvis = Elvis.INSTANCE; elvis.leaveTheBuilding(); } }
4、通过私有构造器强化不可实例化的能力
- 解释:有些类比如静态类,工具类不想被实例化,这些类实例化毫无意义,但是编译器会默认一个构造方法,在已发行的API里面就经常能看到一堆毫无意义的方法。
- 解决:显式的声明构造方法,然后定义为private
- 缺点:继承它的子类将没有默认的超类构造方法可用,都需要声明构造方法
- 其他:在私有构造方法中加:throw new AssertionError();会防止类内部实例化,并不是必须的
- 个人看法:估计这个我们是用不到了。思想很好,在多用组合少用继承的大方向下这个很能提现专业
5、避免创建不必要的对象
- 代码
private static final Date BOOM_START; // 在静态域内初始化 private static final Date BOOM_END; // 在静态域内初始化 static { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); BOOM_START = gmtCal.getTime(); gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); BOOM_END = gmtCal.getTime(); } public boolean isBabyBoomer() { return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0; }
- 解释:将只需要创建一次的对象放入静态域里防止多次创建
- 注意:
- 防止无意识的自动装箱,在运算的时候使用基本类型
- 小对象只做很少量的显式工作,所以小对象的创建和回收动作是非常廉价的,能提升程序的清晰性、简洁性和功能性,一般是好事。所以要看现实,注意不要创建不必要的对象
6、消除过期的对象引用
- java是自动内存管理的,但是有一些漏洞
- 如果一个栈先是增长,然后再收缩,那么从栈中弹出来的对象将不会当作垃圾回收
- 代码:将弹出的对象设为null即可
Object result = elements[--size]; element[size] = null;
- 总结
- 不用过分小心,如果是一个不那么复杂的方法,方法结束则自动清理了
- 一般而言,一旦元素被释放了,则该元素中包含的任何对象引用都应该被清空
7、避免使用终结方法
- 作者很直接,明确finalizer是应该避免的
阅读全文
0 0
- EffectiveJava 学习总结(一)
- EffectiveJava 学习总结(二)
- EffectiveJava 学习总结(三)
- EffectiveJava 学习记录 一
- EffectiveJava学习笔记(1)
- EffectiveJava心得一
- EffectiveJava学习笔记
- EffectiveJava学习1
- EffectiveJava
- EffectiveJava
- 学习总结(一)
- 学习总结(一)
- 学习总结(一)
- EffectiveJava笔记(一) 创建和销毁对象
- dom4j学习总结(一)
- dom4j学习总结(一)
- ant学习总结(一)
- dom4j学习总结(一)
- Java 线程组,Callable,Future,线程池,ThreadLocal类,包装线程不安全的集合
- 之江学院第0届校赛决赛 K-qwb与小数
- PHP脚本对Cookie的读取
- python Flask框架数据库一对多关系,监听器
- 好玩的分词——绘制《三体》全集词云
- EffectiveJava 学习总结(一)
- Android ToggleButton,Switch控件完整案例
- 机器学习中的范数规则化之(一)L0、L1与L2范数
- SOAP Web Services 简介
- Linux学习(四):移动命令mv的注意事项
- 洛谷 P2104 二进制
- USCAO-Section 1.3 Wormholes
- oracle对表空间 USERS 无权限(转载)
- ASIS 2015 Finals: Example flag (trivia1)