Effective-java第二三四章
创建和销毁对象
用静态工厂方法代替构造器,公有的静态工厂方法,只是返回类的实例的静态方法
1 有名称,可以确切的描述返回的对象,可以区分多个静态工厂方法之间的区别
2 不必每次都创建一个新对象,避免创建重复对象
3 可以返回原返回类型的任何子类型的对象
4 添加参数,让返回对象的类可以随着调用而变化
5 方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在
6 类如果不含公有的或者受保护的构造器,就不能被子类化
7 如果没有合适的命名,不容易被发现。常见命名规则:
from:类型转换方法,单个参数,Date d = Date.from(instant)
of:聚合方法,多个参数,EnumSet.of(jack,queen,king)
valueOf: Biginteger p = Biginteger .valueOf(123);
instance或者getInstance
create或者newInstance:每次调用返回一个新实例
getType:type表示工厂方法所返回的对象类型
newType:type表示工厂方法所返回的对象类型
type:getType 和 newType 的简版
遇到多个构造器参数时要考虑使用建造者模式
1 重叠构造器:第一个构造器只有必要参数,第二个构造器多一个可选参数,第三个构造器多两个可选参数,最后一个包含所有可选参数。
2 JavaBeans模式:先调用一个无参数构造器,然后调用set方法设置必须的参数。
3 建造者模式:class.bulider().bulid()。
4 如果有太多参数时,builder模式是一个不错的选择
用私有构造器或者枚举类型强化singleton属性
1 singleton是指只实例化一次的类
2 私有构造器仅被调用一次,实例化公有的静态final域。容易被反射破解
3 静态工厂方法
3 声明一个包含单个元素的枚举类型
通过私有构造器强化不可实例化的能力
1 只包含静态方法和静态域的类,可以这样
优先考虑依赖注入来引用资源
1 依赖注入:当创建一个新实例时,就将该资源传到构造器中
避免创建不必要的对象
1 优先使用基本类型而不是装箱基本类型,小心无意识的自动装箱
消除过期的对象引用
1 缓存
2 监听器和回调
避免使用终结方法和清除方法
1 终结方法是不可预测的,也是很危险的,一般情况下也是不必要的
2 注重时间的任务不应该由终结方法或者清除方法来完成
3 永远不要依赖终结方法或者清除方法来更新重要的持久状态
4 有严重的性能损失
try-with-resources优先于try-finally
1 必须实现AutoCloseable接口
2 代码更简洁,清晰
对于所有对象都通用的方法
覆盖equals时请遵守通用约定
1 类的每个实例本质上都是唯一的
2 类没有必要提供逻辑相等的功能
3 超类已经覆盖了equals,超类的行为对于这个类也是合适的
4 自反性:对于任何非 null 的引用值 x,x . equals(x)必须返回 true
5 对称性:对于任何非 null 的引用值 x 和 y,y.equals(x)返 回 true 时, x.equals(y)必须返回 true
6 传递性:x.equals(y)true ,并且 y.equals(z )true ,那么 x.equals(z )也必须返回 true
7 一致性:对象中所用的信息没有被修改,结果一致
8 对于任何非 null 的引用值 x, x.equals (null)必须返回 false
覆盖equals时总要覆盖hashcode
1 覆盖了equals的方法的类中,必须覆盖hashcode方法
2 只要对象的equals比较操作所用到的信息没有修改,那么hashcode方法必须始终返回同一个值
3 如果根据equals方法比较是相等的,那么hashcode也必须产生同样的结果
4 如果根据equals方法比较是不相等的,hashcode不一定必须不相等。不过最好不相等
始终要覆盖toString
1 好的toString实现可以使类用起来更加舒适,更便于调试
2 tostring应该返回对象中所有值得关注的信息
谨慎的覆盖clone
1 实现cloneable接口的类是为了提供一个功能适当的公有的clone方法
2 对象拷贝更好的方法是提供一个拷贝构造器或拷贝工厂
考虑实现comparable
类和接口
使类和成员的可访问性最小化
1 顶层的类和接口,只有两种访问级别:包级私有的(package-private)和公有的(public)
2 公有类的实例域绝不能是公有的
要在公有类而非公有域中使用访问方法
1 如果类是在包之外进行访问,就提供访问方法
2 如果类是包级私有,或者是私有的嵌套类,直接暴露它的数据域并没有本质的错误
使可变性最小化
1 不可变类,不要提供任何会修改对象状态的方法
2 不可变类,保证类不会被扩展
3 不可变类,所有的域都是final的
4 不可变类,所有的域都是私有的
5 不可变类,确保对于任何可变组件的互斥访问
6 不可变类,本质上是线程安全的,不要求同步,可以自由地共享
7 不可变类,对于每个不同的值都需要一个单独的对象
复合优先于继承
1 继承打破了封装性
要么设计继承并提供文档说明,要么禁止继承
1 文档说明它可覆盖的方法的自用性
2 类必须以精心挑选的受保护的方法,提供适当的钩子,以便进入其内部工作
3 为了继承而设计的类,唯一的测试方法就是编写子类
4 构造器不能调用可被覆盖的方法
5 为了继承而设计的类,对这个类会有一些实质性的限制
接口优于抽象类
为后代设计接口
1 java8之后接口允许添加缺省方法
接口只用于定义类型
1 常量接口,只包含静态的final域,是对接口的不良使用
类层次优于标签类
静态成员类优于非静态成员类
限制源文件为单个顶级类