effective java讀書筆記之 第一章 建立和銷燬物件
阿新 • • 發佈:2019-01-26
第一條: 考慮用靜態工廠方法代替構造器
1.與構造器不同的第一大優勢在於他們有名字,方便使用者呼叫,特別是對於引數各個不同的構造器相比,更為清楚.
2.不必在每次呼叫時都建立一個新的物件,可以為重複呼叫返回相同的物件,同時減少物件的重複建立,節省系統的開銷.
3.他們可以返回原返回型別任何的子類物件,顯得更靈活.
示例程式碼如下:
package main.java.factory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Paul
* @version 0.1
* @date 2018/4/21
*/
public class Services {
//構造方法私有
private Services() {
}
private static final Map<String, Factory> providers = new ConcurrentHashMap<>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
public static void registerDefaultProvider (String name, Factory p) {
registerProvider(DEFAULT_PROVIDER_NAME, p);
}
private static void registerProvider(String defaultProviderName, Factory factory) {
providers.put(defaultProviderName, factory);
}
//用預設工廠建立服務
public static service newInstance() {
return newInstance(DEFAULT_PROVIDER_NAME);
}
//用指定工廠建立服務
public static service newInstance(String name) {
Factory factory = providers.get(name);
if (factory == null) {
throw new IllegalArgumentException("No factory registered with name" + name);
}
return factory.newService();
}
}
interface Factory {
service newService();
}
interface service {
//服務方法介面
}
它的缺點在於如果類中不含有public或者protect構造器,就無法子類化,此外靜態工廠方法與類中其他靜態方法實際上也沒有區別,因此可能會難以區分.
第二條: 當成員變數過多時考慮用builder代替構造器
提供了javaBean模式之外的另一種構建方法,保證了執行緒安全同時具有良好可讀性.
package main.java.factory;
/**
* @author Paul
* @version 0.1
* @date 2018/4/22
*/
public class Student {
private final String name;
private final int age;
private final int code;
private final String clazz;
public static class Builder {
private final String name;
private final int age;
private int code = 0;
private String clazz = null;
public Builder(String name, int age) {
this.name = name;
this.age = age;
}
public Builder code(int code) {
this.code = code;
return this;
}
public Builder clazz(String clazz) {
this.clazz = clazz;
return this;
}
public Student bulid() {
return new Student(this);
}
}
public Student(Builder builder) {
name = builder.name;
age = builder.age;
code = builder.code;
clazz = builder.clazz;
}
public static void main(String[] args) {
//客戶端呼叫
Student student=new Builder("paul", 12).code(2).clazz("一班").bulid();
}
}
第三條: 使用私有構造器或列舉強化singleton,以及保證其不可例項化
將構造方法私有化,同時在類內部通過publis static final 構造一個物件供外部呼叫,保證全域性唯一性.
第四條: 避免創造不必要的物件
對於同時提供了構造器和靜態工廠方法的final類優先使用靜態工廠方法.以便重用final物件
第五條: 避免使用終結方法,消除過期的物件引用