第2章 创建和销毁对象
第1条:考虑用静态工厂方法代替构造器
静态工厂方法,只是一个返回类的实例的静态方法。
示例:boolean基本类型转化成Boolean对象引用
public static Boolean valueOf(boolean e){
return b ? Boolean.TRUE : Boolean.FALSE;
}
优势:
1.有名称,也就是说看着清楚白。
2.不必在每次调用的时候都创建新的对象。(避免了创建不必要的重复对象,从而提高了性能)
重复的调用返回相同对象
实例受控的类:确保是单例,或者不可实例化,
使得不可变的类可以确保不会存在两个相等的实例,当且仅当==时equals() 是true
3.可以返回原返回类型的任何子类型的对象。
4.在创建参数化类型实例的时候,使代码变得更加简洁。
构造器参数
Map<String,List<String>> map = new HashMap<String,List<String>>();
静态方法---类型推导
Map<String,List<String>> map = HashMap.newInstance();
public static <K,V> HashMap<K,V> newInstance(){
return new HashMap<K,V>();
}
缺点:
1.类如果不包含公有或者受保护的构造器,就不能被子类化。
其实并不是什么缺点,鼓励使用复用,而不是继承。(16条)
2.与其他静态方法实际上没有任何区别。
但是有惯用的名称:valueOf,of,newInstance,getInstance,getType,newType等
第2条:遇到多个构造器参数时要考虑用构建器
最容易想到的就是,重叠构造器模式。但是随着参数增多,造成编写困难,阅读困难。
1.JavaBean模式 :调用默认的无参构造器创建对象,然后使用setter方法来设置每个参数(实践中很少用)
当然有缺点:
构造过程JavaBean可能处于不一致的状态。
JavaBean模式阻止了将该类做成不可变的可能。(15条)
2.Builder模式 24
此处有实例
如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是种不错的选择。
*** 第3条:用私有构造器或者枚举类型强化Singleton属性 ***
Singleton 指仅仅被实例化一次的类。
工厂方法的优势:提供了灵活性;泛型
单元素的枚举类型已经成为实现单例的最佳方法
public enum Elvis{
INSTANCE;
public void leaveTheBuilding(){……}
}
*** 第4条:通过私有构造器强化不可实例化的能力 ***
私有构造器,记得加注释。
*** 第5条:避免创建不必要的对象 ***
最好能重用对象而不是每次需要的时候都创建一个相同功能的新对象。
如果对象是不可变的,它就始终可以被重用。
静态的初始化器
static{
...
}
要优先使用基本类型而不是装箱基本类型,要当心无意识的自动装箱。
*** 第6条:消除过期的对象引用 ***
Stack类自己管理内存。存储池包含了elements数组(对象引用单元,而不是对象本身)的元素。
数组活动区域的元素是已分配的,而数组其余部分的元素是自用的。但是GC不知道。
只要类是自己管理内存,就应该警惕内存泄露问题。
缓存:用WeakHashMap
LinkedHashMap是利用它的removeEldlestEntry方法实现
对于更复杂的缓存,使用 java.lang.ref
监听器和其他回调
回调立即被当成gc :只保存他们的弱引用(weak reference),如保存成WeakHashMap的键
Heap剖析工具---Heap Profiler
*** 第7条:避免使用终结方法 ***
终结方法 (finalizer)
不应该依赖终结方法来更新重要的持久状态。
System.gc 和 System。runFinalization 并不保证终结方法一定会被执行。
显式的终止方法——一般与try-finally结构一起使用:
InputStream,OutputStream,sql的close()
Timer的cancel()
终结方法的好处:为了安全,与对象的本地对等体有关
将终结方法放到一个匿名的类里:终结它的外围实例----终结方法守卫者
继续补充中。。。