Effective Java -- 创建和销毁对象
2023-09-14 09:00:30 时间
静态工厂方法代替构造器
- 可以返回原返回类型的任何子类型对象;
- 不必每次调用他们的时候都去创建一个对象;
- 有名称;
- 创建参数化类型实例的时候,使得代码更加简洁。
静态工厂方法的缺点:
- 如果不含公有的或者受保护的构造器,就 不能被子类实例化;
- 与其他的静态方法实际上没有任何区别。
遇到多个构造器参数的时候考虑使用builder模式
- 利用javaBean的set方法来设置;
- 最佳方法:使用Builder模式来构造多参数的类对象。
builder模式优点:
- 灵活,可以利用单个builder构建多个对象;
- 可以在创建对象期间进行调整,也可以随着不同对象改变。
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; public static class Builder { // Required parameters private final int servingSize; private final int servings; // Optional parameters - initialized to default values 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() { return new NutritionFacts(this); } } private NutritionFacts(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) { NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8) .calories(100).sodium(35).carbohydrate(27).build(); } }
用私有构造器或者枚举类型强化单利
使用枚举:
public enum Elvis { INSTANCE; public void leaveTheBuilding() { System.out.println("Whoa baby, I'm outta here!"); } // This code would normally appear outside the class! public static void main(String[] args) { Elvis elvis = Elvis.INSTANCE; elvis.leaveTheBuilding(); } }
通过构建私有构造器强化不可实例化的能力
public class UtilityClass { // Suppress default constructor for noninstantiability private UtilityClass() { throw new AssertionError(); } }
子类继承报错,其他类调用也会出错。
避免创建不必要的对象
能重用对象绝不创建新对象。
优先使用基本类型而不是装箱基本类型,要当心无意义的自动装箱。
class Person { private final Date birthDate; public Person(Date birthDate) { // Defensive copy - see Item 39 this.birthDate = new Date(birthDate.getTime()); } // Other fields, methods /** * The starting and ending dates of the baby boom. */ 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; } }
消除过期对象的引用
- 一旦引用过期,就需要对引用进行清空。
- 使用weakHashMap代表缓存,当缓存过期,自动删除。
- 确保回调立即被当做垃圾回收的最佳方法是保持它们的弱引用。
避免使用终结方法
终结方法不可预测,很危险,不必要。
java语言不保证终结方法及时执行,不保证会被执行。能够保证终结方法被执行的方法是System.runFinalizersOnExit(),Runtime.runFinalizersOnExit()。
使用终结方法存在严重的性能问题。
显示终止方法例子:IO流中的close方法。Timer的cannel方法。
如果使用终结方法,也要记住调用super.finalize。
相关文章
- Java 开发环境配置--eclipse工具进行java开发
- Java IO--对象序列化Serializable、ObjectOutputStream、ObjectInputStream、transient
- java学习笔记4--对象的初始化与回收
- Java实现 洛谷 P1055 ISBN号码
- Java实现 蓝桥杯 历届试题 错误票据
- Java实现 蓝桥杯VIP 算法训练 黑白无常
- Java实现 蓝桥杯VIP 算法训练求先序排列
- Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
- Java通过mysql-connector-java-8.0.11连接MySQL Server 8.0遇到的几个问题
- 【JAVA】java编译错误:编码UTF8/GBK的不可映射字符
- JAVA编程思想读书笔记(四)--对象的克隆
- 【JAVA】基于MVC架构Java技术荟萃案例演练
- 【JAVA】 02-Java对象细节
- 【Java】java使用反射访问对象方法和成员变量
- paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)
- 战斗到底:Java vs. Python - 用哪个更适合处理海量数据?
- 【java】Java教程
- 【java】Java 枚举(enum)如何使用以及原理
- java使用BeanUtils封装file类型表单数据到一个对象中
- Java反射获取类对象的三种方式
- Java集合源码学习(一)Collection概览
- java对象和json数据转换实现方式3-使用jackson实现
- Java中介者模式:解密对象间的潜在火药桶
- 【java】Java线程池实现原理及业务中的实践
- 第一篇:Java中一切都是对象