Effective Java知识总结(1)
注:文章内容总结于《Effective Java》,特此声明。
静态工厂方法代替构造器
类可以提供一个共有的静态工厂方法,它只是一个返回类的实例的静态方法。如:
public static Boolean valueOf(boolean b) {
return b ? Boolean.TURE : Boolean.FALSE;
}
静态工厂方法的优势
- 静态工厂方法具有名称。构造器的参数本身有可能没有确切地描述正被返回地对象,而静态工厂可以具有适当地名称来描述其返回地对象。
- 静态工厂方法不必在每次调用它们地时候都创建一个新对象。静态工厂方法能够为重复地调用返回相同地对象,有助于类总能严格地控制在某个时刻有哪些实例应该存在(实例受控地类)。
- 静态工厂方法可以返回原返回类型地任何子类型地对象。这种灵活性可以使API返回对象,同时又不会使对象地类变成共有的。
- 静态工厂方法在创建参数化类型实例的时候,它们使代码变得更加简洁。使用静态工厂方法的时候,编译器可任意替你找到类型参数,称为类型推导(type inference)。
public static <K,V> HashMap<K,V> newInstance() {
return new HashMap<K,V>();
}
Map<String, List<String>> m = HashMap.newInstance();
静态工厂方法的缺点
- 使用静态工厂方法,类如果不含公有的或者受保护的构造器,就不能被子类化。
- 使用静态工厂方法和使用其他的静态方法实际上没有任何区别。
遇到多个构造器参数时要考虑使用构建器
使用构造器和静态 工厂方法饭都不能很好地扩展到大量的可选参数。有时会使用重叠构造器来满足这一需求,但是当有很多参数的时候,客户端代码就会很难编写也难以阅读。有时可以使用JavaBeans模式,调用一个无参构造器来创建对象,然后使用setter方法来设置每个必要的参数,以及每个相关的可选参数,但是在构建过程中JavaBean可能处于不一致夫人状态。
第三种方法是使用Builder模式,不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象,然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数,最后客户都拿调用无参的build方法来生成不可变的对象。
避免创建不必要的对象
一般来说,最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象。如果对象是不可变的,它就始终可以被重用。例如,
String s = new String("stringette");
上述语句在每次被执行的时候都创建一个新的String实例,都是完全没有必要的,传递给String构造器的参数本身就是一个String实例。因此,可以这样写
String s = "stringstte";
它只创建一个String实例,而不是每次执行的时候都创建一个新的实例。
对于同时提供了静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法而不是构造器,以避免创建不必要的对象。
除了重用不可变的对象之外,也可以重用那些已知不会修改的可变对象。
消除过期的对象引用
在支持垃圾回收的语言中,需要警惕内存泄漏的问题。在某些情况下,对象的引用会被无意识的保持,垃圾回收机制不会清除这个对象,也不会处理被这个对象所引用的所有其他对象。例如,如果一个栈先是增长再是收缩,那么从栈中弹出的对象将不会被当作垃圾回收,在栈的内部维护着对这些对象的过期应用。
清除过期引用的方法:一旦对象引用已经过期,只需清空这些引用即可。
一般而言,只要一个类是自己管理内存,程序员就应该警惕内存泄漏的问题。一旦元素被释放掉,则该元素中包含的任何对象引用都应该被清空。
内存泄漏的来源还包括缓存、监听器和其他回调。