第一條:考慮靜態(tài)工廠方法代替構(gòu)造器
靜態(tài)工廠方法的優(yōu)勢:
- 有名稱(例子中的probablePrime)
BigInteger b = BigInteger.probablePrime(9, new Random());
- 不必每次調(diào)用它們的時候都創(chuàng)建一個新對象
Boolean.valueOf()方法源代碼,因為只有兩種狀態(tài),所有先聲明兩個public static final 的Boolean對象举娩,調(diào)用的時候就不會有對象的實例化過程了帅涂。
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
- 可以返回類型的任何子類型
暫時還無法理解
- 使代碼更加簡潔
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
HashMap<String, String> hashMap = MyHashMap.newInstance();
hashMap.put("name", "Sherlock Moon");
System.out.println(hashMap.get("name"));
}
static class MyHashMap<K, V> extends HashMap<K, V> {
private static final long serialVersionUID = 1L;
public static <K, V> HashMap<K, V> newInstance() {
return new HashMap<K, V>();
}
}
}
靜態(tài)工廠方法的劣勢
類如果不含公有的或者受保護(hù)的構(gòu)造器姚淆,就不能被子類化勤哗。
它們與靜態(tài)方法沒有區(qū)別于样,難以分清疏叨。解決辦法:
統(tǒng)一方法名:valueOf : 返回的實例與參數(shù)值相同,比如:String.valueOf()穿剖。
of : valueOf的替代蚤蔓。
getInstance : 沒有參數(shù),返回唯一的實例糊余。如Calendar.getInstance秀又。
newInstance :返回的實例和所有其他的實例不同单寂。
getType :和getInstance一樣,Type表示工廠方法所返回的對象類型涮坐。
newType :和newInstance一樣凄贩。
* 第二條:遇到多個構(gòu)造器參數(shù)時要考慮用構(gòu)建器
package test;
public class Student {
private final Long userId;
private final String userPassword;
private String userEmail = null;
public static void main(String[] args) {
Student s = new Student.Builder(123456L, "xxxyyyzzz").email("1@2.com").build();
System.out.println(s.toString());
}
private Student(Builder builder) {
this.userEmail = builder.userEmail;
this.userId = builder.userId;
this.userPassword = builder.userPassword;
}
public static class Builder {
private final Long userId;
private final String userPassword;
private String userEmail;
public Builder(Long userId, String userPassword) {
this.userId = userId;
this.userPassword = userPassword;
}
public Builder email(String val) {
this.userEmail = val;
return this;
}
public Student build() {
return new Student(this);
}
}
@Override
public String toString() {
return "userName : " + this.userId
+ "\nuserPassword : " + this.userPassword
+ "\nuserEmail : " + this.userEmail;
}
}
/*
userName : 123456
userPassword : xxxyyyzzz
userEmail : 1@2.com
*/
* 第三條:用私有構(gòu)造器或者枚舉類型強(qiáng)化Singleton屬性
public class SingletonTest {
public final static int DEFAULT_WIDTH = 10;
public final static int DEFAULT_HEIGHT = 10;
private int width;
private int height;
private final static SingletonTest INSTANCE = new SingletonTest(DEFAULT_WIDTH, DEFAULT_HEIGHT);
private SingletonTest(int width, int height) {
this.width = width;
this.height = height;
}
public static SingletonTest getInstance() {
return INSTANCE;
}
@Override public String toString() {
return "width : " + this.width
+ "\nheight : " + this.height;
}
public static void main(String[] args) {
SingletonTest s = SingletonTest.getInstance();
System.out.println(s.toString());
s.height = 8;
SingletonTest s1 = SingletonTest.getInstance();
System.out.println(s1.toString());
}
}
/*
width : 10
height : 10
width : 10
height : 8
*/
* 第四條:通過私有構(gòu)造器強(qiáng)化不可實例化的能力
有些工具類不需要實例化,比如全是常量的類袱讹。
public class ConstantParam {
//防止實例化
private ConstantParam() {
}
public static final int MAX_TRY_TIMES = 10;
public static final String HOST = "www.reibang.com";
}
第五條:避免創(chuàng)建不必要的對象
- 如果對象是不可變的,它就始終可以被重用.
下面利用static代碼塊重用對象
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Five {
private static final Date START;
private static final Date END;
static {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(1900, Calendar.JANUARY, 1, 0, 0, 0);
START = cal.getTime();
cal.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
END = cal.getTime();
}
/**
* 是否是20世紀(jì)
* @param date
* @return
*/
public static boolean isTwentyCentury(Date date) {
return date.compareTo(START) >= 0 &&
date.compareTo(END) < 0;
}
public static void main(String[] args) {
System.out.println(isTwentyCentury(new Date()));
Calendar c = Calendar.getInstance();
c.set(1901, Calendar.MARCH, 1, 0, 0, 0);
Date d = c.getTime();
System.out.println(isTwentyCentury(d));
}
}
/**
* false
* true
*/