title: Effective Java 3rd 讀書筆記(一)
date: 2019-02-19 18:05:09
tags: java
categories: 讀書筆記
才發(fā)現(xiàn) Effective Java 已經(jīng)出到第三版了,重新看一遍并且記錄下,這一篇先更靜態(tài)工廠方法
靜態(tài)工廠方法
使用靜態(tài)方法向外界提供自身實例的方法
Fragment fragment = MyFragment.newIntance();
// or
Calendar calendar = Calendar.getInstance();
使用靜態(tài)工廠代替構(gòu)造方法
在原生java中,有很多使用靜態(tài)工廠方法代替構(gòu)造方法的例子,比如Boolean
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
使用靜態(tài)工廠有幾個優(yōu)點:
可以使用名字去提示這個方法的返回
不使用new 去創(chuàng)建實例,通過靜態(tài)方法名字去代表不同創(chuàng)建實例的行為,例如valueOf,newInstance等,這樣代碼的編寫和閱讀都能夠更清晰。
允許在每次調(diào)用時,不創(chuàng)建新的對象
例如Boolean: Boolean.valueOf(boolean),永遠不會返回新的對象。因此可以省去頻繁創(chuàng)建相同對象所造成的性能損耗,減少內(nèi)存占用;同時做到“控制實例”??梢詤⒖?a target="_blank" rel="nofollow">享元模式的思路。此外java中的單例模式也是使用靜態(tài)工廠方法,具體寫法參考單例模式的八種寫法
可以返回該類型的任何子類
作為輸入?yún)?shù)的函數(shù),返回對象的類可以隨調(diào)用的不同而變化。
例如EnumSet 類沒有公共構(gòu)造函數(shù),只有靜態(tài)工廠。
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
//根據(jù)不同長度,返回不同的子類實例
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
當(dāng)編寫包含方法的類時,返回對象的類不需要存在
考慮服務(wù)提供者框架(service provider frameworks),其包含提供者注冊API(提供者用來注冊實現(xiàn)),服務(wù)接口,以及服務(wù)準(zhǔn)入API(客戶端用來獲取服務(wù)實例),此外還有可選的第四個組件:服務(wù)提供接口,用于描述生成服務(wù)接口實例的工廠對象。在沒有服務(wù)提供者接口的情況下,必須以反射的方式實例化實現(xiàn)
通過服務(wù)準(zhǔn)入API,客戶端可以通過定制標(biāo)準(zhǔn)來選擇不同的實現(xiàn)。參考JDBC:Connection=服務(wù)接口;DriverManager.registerDriver=提供者注冊API;DriverManager.getConnection=服務(wù)準(zhǔn)入API
//TODO JDBC源碼分析
靜態(tài)工廠常用名稱
- from: 一種型轉(zhuǎn)換方法,該方法接受單個參數(shù)并返回該類型的相應(yīng)實例
- of: 一個聚合方法,它接受多個參數(shù)并返回一個包含這些參數(shù)的此類實例
- valueOf: 一種替代 from 和 of 但更冗長的方法
例如:BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE); - getInstance: 返回一個實例,該實例由其參數(shù)(如果有的話)描述,但不具有相同的值
- newInstance: 只是該方法保證每個調(diào)用都返回一個新實例
- get{Type}: 與
getInstance類似,但如果工廠方法位于不同的類中,則使用此方法。類型是工廠方法返回的對象類型 - newType: 與
newInstance類似,但是如果工廠方法在不同的類中使用。類型是工廠方法返回的對象類型