本篇主要總結的是《Effecticve Java》中關於創建和銷毀對象的內容。
比如:
- 何時以及如何創建對象
- 何時以及如何避免創建對象
- 如何確保及時銷毀
- 如何管理對象銷毀前的清理動作
考慮用靜態工廠方法代替構造器
使用靜態工廠的優勢:
- 有名稱
- 不必每次調用的時候都創建一個新的對象
- 返回原返回類型的任何子類型對象
- 在創建參數化類型實例時,代碼更加簡潔。
使用靜態工廠的缺點:
- 類如果不包含公有的或者受保護的構造器,就不能被子類化
- 與其他的靜態方法實際上沒有任何區別
舉個例子:
public class Apple{
public Apple(String type){}
public static Apple newInstance(){
return new Apple("qing");
}
}
//使用的時候直接newInstance就可以
Apple.newInstance();
常用的靜態工廠名稱:valueOf
,of
,getInstance
,newInstance
,getType
,newType
.
遇到多個構造器參數時考慮使用構建器
如果參數很多,在使用的時候也會很繁瑣。比如
new Person(name,age,address,tel,gender);
當參數大於三個的時候,就可以考慮使用構建器了,特別實在參數可選的時候。
public class Person{
public Person name(String name){return this;}
public Person age(String age){return this;}
public Person gender(String gender){return this;}
public Person tel(String tel){return this;}
}
//使用的時候可以這樣用
(new Person()).name("xingoo").age(30).gender("male").tel(13333333333);
使用構建器的缺點就是代碼會比較冗長。
用私有構造器或者枚舉類型強化Singleton屬性
第一種方式,是餓漢模式:
publci class Elvis{
public static final Elvis INSTANCE = new Elvis();
private Elvis(){}
public void xxx(){}
}
另一種方式,屬於懶漢模式:
public class Elvis{
private static Elvis INSTANCE;
private Elvis(){}
public static Elvis getInstance(){
if(INSTANCE == null)
INSTANCE = new Elvis();
return INSTANCE;
}
xxx
}
通過私有構造器強化不可實例化的能力
有一些比如工具類,是不想被實例化的,可以使用私有的構造方法,來避免實例化:
public class XXUtil{
private XXUtil(){}
}
缺點是這樣的類無法被子類化。
避免創建不必要的對象
盡量應該避免創建不必要的對象,比如:
String s = new String("xxx");
其實創建了兩個字符串對象。
盡量優先使用long這種基本類型。
消除過期的對象引用
常見的是在棧操作,出棧操作並不意味着釋放對象。
public Object pop(){
if(size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null;
return result;
}
避免使用終結方法
finalizer方法是再垃圾回收的時候觸發的,因此不能准確的知道終結方法調用的時間。因此最好是在try catch finally的時候釋放對象。
這種釋放對象的時機,叫做顯示終止方法。