1 创建对象和销毁对象
第1条 用静态工厂方法代替构造器
静态工厂方法与构造器不同的第一大优势在于,他们有名称;第二大优势在于,不在每次调用它们的时候都创建一个新的对象;第三大优势在于,它们可以返回类型的任何子类型的对象;第四大优势在于,所返回的对象的类可以随着每次的调用而发生变化,这取决于静态工厂方法的参数值;第五大优势在于,方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在。
第2条 遇到多个构造器参数时要考虑使用构造器
JavaBeans模式、Builder模式
第3条 用私有构造器或者枚举类型强化Singleton属性
单元素的枚举
第4条 通过私有构造器强化不可实例化的能力
第5条 优先考虑依赖注入来引用资源
静态工具类和Singleton类不适合于需要引用底层资源的类
当创建一个实例时,将资源传到构造器(或者静态工厂、构建器)中,这是依赖注入的一种形式。
依赖注入框架:Daggr、Guice、Spring
第6条 避免创建不必要的对象
比如String.matches方法最易于查看一个字符串是否和正则表达式相匹配,单不适合在注重性能的情形中重复使用。问题在于它在内部创建了一个Pattern实例,却只使用了一次,就被垃圾回收了;而创建Pattern成本很高。
而是应该在类初始化时创建private static final Pattern r = Pattern.compile("^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{9,}$"); 使用时直接调用即可 r.matcher(str).matches()
第7条 消除过期的对象引用
内存泄漏:过期的引用,缓存,监听器和其他的回调。
第8条 避免使用终结方法和消除方法
第9条 try-with-resources优先于try-finally
因为不需要再调用close()方法,只要实现了AutoCloseable接口,都可以使用。
2 对于所有对象都通用的方法
第10条 覆盖equals时请遵守通用约定
自反性、对称性、传递性、一致性、对于任何非null的引用值x,x.equals(null)必须返回false。不要轻易覆盖equals方法,除非迫不得已。
第11条 覆盖equals时总要覆盖hashcode
如果不这样做的话,导致该类无法结合所有基于散列的集合一起正常使用;如HashMap 、HashSet等。
第12 始终要覆盖toString
第13条 谨慎地覆盖clone
clone方法就像另一个构造器,必须确保它不会伤害到原始的对象,并确保正确的创建被克隆对象中的约束条件。Clone方法禁止给final域赋新值的,除非在原始对象和克隆对象之间可以安全的共享此对象。为了使类成为可克隆的,可能有必要从某些域中去掉final修饰符。
第14条 考虑实现Comparable接口
3 类和接口
第15条 使类和成员的可访问性最小化
尽可能的使每个类或者成员不被外界访问
第16条 要在公有类中使用访问方法而非公有域
第17条 使可变性最小化
1 不要提供任何修改对象状态的方法
2 保证类不会被拓展
3 声明所有的域都是final的
4 声明所有域都是私有的
5 确保对于任何可变组件的互斥访问
不可变对象本质上是线程安全的,它们不要求同步;不可变对象可以被自由的共享。
第18条 复合优先于继承
继承会把超类API中的所有缺陷传播到子类中,而复合则允许设计新的API来隐藏这些缺陷。继承违背了封装原则。复合:现有的类变成新类的一个组件。新类中的每个实例方法都可以调用被包含的现有类实例中对应的方法,并返回它的结果。这样得到的类更加稳固,它不依赖于现有类的实现细节。现有的类添加了新的方法,也不会影响新的类。
第19条 要么设计继承提供文档说明,要么禁止继承