1. 程式人生 > >effective java 第2章 建立和銷燬物件筆記

effective java 第2章 建立和銷燬物件筆記

第一條:考慮用靜態工廠方法替代構造器

靜態工廠方法的優點:

1.具有名字,有可閱讀性。

2.不必在每次呼叫他們的時候都建立一個新物件。
應用:①單例物件 ②列舉
3.可以返回返回值型別的任何子型別的物件。
應用:
①EnumSet的靜態工廠方法根據元素的個數選擇返回RegalarEnumSet還是JumboEnumSet,從而隱藏了底層的確切返回值。
②服務提供者介面(通過JDBC的Driver、DriverManager和Connection來理解)。
4.在建立引數化型別例項的時候,使得程式碼變得更加簡潔。
靜態工廠方法的缺點: 1.含有該方法的類如果沒有公有或者受保護的構造器就不能被繼承。

public class Father {
    private Father(){
 
    }
}
//報錯
class Son extends Father{
 public static void main(String[] args) {
  Son s = new Son();
 }
}


2.和其他靜態方法實際沒有任何區別,不會被API文件明確標識出來,但遵守標準的命名習慣可以彌補這一劣勢。

第二條:遇到多個構造器引數時要考慮用構建器

1.重疊構造器模式
重疊構造器模式可行,但是當有許多引數的時候,客戶端程式碼會很難編寫,並且閱讀起來比較困難。

2.JavaBeans模式
呼叫一個無參構造器來建立物件,然後呼叫setter方法來設定每個必要的引數。
優點:彌補了重疊構造器模式的不足,易建立,易閱讀。
缺點:在構造過程中JavaBean可能處於不一致的狀態。並且該模式阻止了把類做成不可變類的可能,這要付出額外的代價來確保它的執行緒安全。

3.Builder模式

優點:既能保證重疊構造器模式那樣的安全性(個人理解為可構建不可變類,即執行緒安全)又能保證像JavaBeans的可讀性。
大致過程:
不直接生成想要的物件,而是讓客戶端利用所有必要的引數呼叫構造器,得到一個builder物件,然後客戶端通過builder物件呼叫類似setter的方法來設定可選引數,最後,利用builder物件呼叫build方法來生成不可變的物件。
關於內部類的部落格:http://www.cnblogs.com/dolphin0520/p/3811445.html,這個博主寫的非常好,基礎篇看完後更為深刻地理解了內部類。
關於builder設計模式的部落格: http://www.importnew.com/6605.html

第三條:用私有構造器或列舉型別強化Singleton屬性

1.通過final的公有靜態成員來允許客戶端訪問類的唯一例項
缺點:有可能借助AccessibleObject.setAccessible方法通過反射機制呼叫私有構造器。
改進:可以通過修改構造器,讓它在被要求建立第二個例項的時候丟擲異常。

2.通過靜態工廠方法

缺點:同點1
優點:①提供靈活性,不改變API的前提下,可以取消單例的想法
            ②與泛型有關

3.編寫一個包含單個元素的列舉型別

優點:無償地提供了序列化機制,防止多次例項化。實現Singleton的最佳方法

第四條:通過私有構造器強化不可例項化的能力

當你編寫工具類utility class(把具體功能組織起來,只包含靜態方法和靜態域的類,如java.lang.Math,java.util.Collections,java.lang.Arrays)時,不希望它被例項化。但在缺少顯式構造器的情況下,編譯器會自動提供一個公有的、無參的構造器。所以應該把構造器私有化。並且可以選擇在構造器方法內部throw new AssertionError(),可以避免不小心在類的內部呼叫構造器。

第五條:避免建立不必要的物件

1.一般來說,最好能夠重用物件而不是每次都建立一個功能相同的物件。
String s = "stringette"應代替String s = new String("stringgette")

2.對於同時提供了靜態工廠方法和構造器的不可變類,應優先使用靜態工廠方法,避免建立不必要的物件。

3.對於一個給定的Map物件,多次呼叫keySet都返回同一個Set例項。

4.要優先使用基本型別而不是裝箱基本型別,要當心無意識的自動裝箱。

5.不要片面的認為“建立物件的代價非常昂貴,我們應該儘可能的避免建立物件”。相反地,有的小物件的構造器只做很少量的顯式工作。所以,小物件的建立和回收是非常廉價的。

6.可以維護自己的常量池來避免建立物件,如資料庫連線池。但也有缺點:程式碼複雜,增加記憶體佔用,損害效能。

7.請分清楚什麼時候該重用物件,什麼時候該建立物件。

第六條:消除過期的物件引用

public class Stack{
	private Object[] elements = new Object(10);
	private int size = 0;

	public void push(Obejct e){
		ensureCapacity();
		elements[size++];
	}

	public Object pop(){
		if(size == 0)
			throw new EmptyStackException();
		return elements[--size];
	}

	//判斷是否需要擴容
	private void ensureCapacity(){
		if(elements.length == size)
			elements = Arrays.copyOf(elements,2 * size + 1);
	}
}

上述程式碼簡單的修改了書本程式碼方便自己理解,因為這個棧類是通過一個變數size來維護容器裡面元素的個數,當彈出棧頂元素時,並沒有真正的刪除陣列對元素的引用,只是size--,實際上元素還是被物件引用著,該元素不會被當作垃圾回收。要解決這個問題只需要將elements[size] = null即可。
但這並不是常見的,清空物件引用應該是一種例外,而不是一種規範行為,多數時候最好定義一個變數在最緊湊的作用域範圍。

何時該清空引用?如上述例子,Stack類自己管理記憶體的情況就應該手工清空引用。

第七條:避免使用終結方法

1.終結方法通常是不可預測的,也是很危險的,一般情況下是不必要的。

2.不應該依賴終結方法來更新重要的持久狀態。

3.使用終結方法有非常嚴重的效能損失。

4.應該提供一個顯式的終止方法(如InputStream的close方法)來替代終結方法。

優點:
①終結方法可以充當“安全網”。避免編寫類時,忘記呼叫顯式的構造方法而導致資源沒有釋放。
②回收“本地對等體”

注意點:
對於一個帶有終結方法的非final公共類,應該考慮使用一個私有例項變數儲存一個匿名內部類例項,該匿名內部類例項重寫終結方法,並在裡面終結外部類。
public class Foo{
	
	private final Object finalizerGuardian = new Object(){
		@Override
		protected void finalize() throws Throwable{
			//終結外部類的操作
		}
	}
}


相關推薦

effective java 2 建立銷燬物件筆記

第一條:考慮用靜態工廠方法替代構造器 靜態工廠方法的優點: 1.具有名字,有可閱讀性。 2.不必在每次呼叫他們的時候都建立一個新物件。 應用:①單例物件 ②列舉 3.可以返回返回值型別的任何子型別的物件。 應用: ①EnumSet的靜態工廠方法根據元素的個數選擇返回Reg

effective java中文版 第二 建立銷燬物件

第1條:考慮用靜態工廠方法替代構造器 如下方法將boolean基本型別值轉換為了一個Boolean物件引用 public static Boolean valueOf(boolean b){ return b ?Boolean.TRUE:Boolean.FALSE; } 靜態

effective java讀書筆記之 第一 建立銷燬物件

第一條: 考慮用靜態工廠方法代替構造器 1.與構造器不同的第一大優勢在於他們有名字,方便使用者呼叫,特別是對於引數各個不同的構造器相比,更為清楚. 2.不必在每次呼叫時都建立一個新的物件,可以為重複呼叫返回相同的物件,同時減少物件的重複建立,節省

《Effect Java》第二"建立銷燬物件筆記

第一條:考慮用靜態工廠方法代替構造器 首先要指明一個誤區:靜態工廠方法不是指的設計模式裡面的工廠方法,他是指以靜態方法的形式建立物件(工廠就是用來建立物件的),例如: public static User createNormalUser(){ return new

《SQL 學習指南》( 3 版)學習筆記(2) - 2 建立使用資料庫

2.1 建立 MySQL 資料庫 (如果要匯入示例 .sql 指令碼檔案,除了書上的 8 個步驟,我另外做幾點修正和補充: a. P 14 面倒數第 4 行給的連結失效了,正確的連結:https://resources.oreilly.com/examples/9780596007

effective java4介面

第13條 使類和成員的可訪問性最小化 第一規則:儘可能地使每個類或成員不被外界訪問 只有當同一個包內的另一個類真正需要訪問一個成員的時候,你才應該刪除private修飾符。 如果方法覆蓋了超類中的一個方法,子類中的訪問級別就不允許低於超類中的訪問級別。這樣可確保任何可使用超類例項的地方也可以

effective java 6 列舉註解 30條 用enum代替int常量

列舉是什麼?        列舉型別是指由一組固定的常量組成合法值的型別。列舉型別是解決常量int的另一種解決方案。 列舉型別的簡單示例: public enum AlarmPoints {STAIR1,STAIR2,LOBBY,OFFICE1,OFFICE2,OFFI

Effective Java (3rd Editin) 讀書筆記:1 建立銷燬物件

1 建立和銷燬物件 Item 1:考慮用靜態工廠方法取代構造器 public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); } 靜態工廠方法的優點: 有名

effective java》讀書筆記1(建立銷燬物件)

第1條:考慮用靜態工廠方法代替構造器 1.what is? 此處的靜態工廠方法與設計模式中的工廠模式不一樣。 比如類 class Person{ //A的構造器 public A(){}; //A的靜態工廠方法可以

Effective Java 讀書筆記(一):建立銷燬物件

1 構造器 => 靜態工廠方法 (1)優勢 靜態工廠方法有名字 靜態工廠方法不必在每次被呼叫時都產生一個新的物件 靜態工廠方法能返回原返回型別的任意子型別的物件 靜態工廠方法根據呼叫時傳入的不同引數而返回不同類的物件 靜態工廠方法返回物件的類不需要存在(SPI架構) (2

Effective Java 建立銷燬物件 3.用私用構造器或者列舉型別強化Singleton屬性

Singleton 也就是常說的單例模式,只能被例項化一次,當然這看操作。 java1.5版本之前,實現Singleton有兩種方法。這兩種方法都要把構造器保持為私有的,並匯出公有的靜態成員,一遍允許客戶端能夠訪問該類的唯一例項。在第一種方法中,公有靜態成員是個final域

2 GNS3PacketTracer網絡模擬器(1)_GNS3概述

下載 功能 安裝位置 ges images 項目目錄 捕獲 png 編寫 1. 安裝和配置GNS3 1.1 GNS3概述 (1)GNS3是一款具有圖形化界面,可運行在多平臺(包括Windows、Linux、Mac OS等)上面的網絡虛擬軟件。 (2)可以在虛擬環境中運行Ci

2 GNS3PacketTracer網絡模擬器(3)_搭建Packet tracer實驗環境

router images conf address 3.2 發送 style 廣域網 eric 3. Packet tracer實驗環境 3.1 設置網絡拓撲圖 (1)配置路由器局域網和廣域網接口,如上圖(可雙擊相應的圖標,然後在命令行或圖形界面上進行IP地址等配置)

《python基礎教程》2列表元組 讀書筆記

append() 列表方法 sort 追加 rev 基礎教程 筆記 buffer 刪除   第二章 列表和元組 1.數據結構:通過某種方式將元素集合在一起。 2.python的6種內建序列:列表,元組,字符串,Unicode字符串,buffer對象,xrange對象。 3.

pathon筆記——2 變數簡單資料型別

1、修改字串大小寫 title()方法:首字母大寫 upper()方法:全部大寫 lower()方法:全部小寫 2、拼接字串 用+直接拼接 3、使用製表符或換行符 製表符\t 換行符\n 4、刪除空白 rstrip()方法:刪除字串末尾空白 lstrip()方法:刪除字串開頭空白 str

java程式設計思想學習筆記——2 一切都是物件

儘管java是基於C的,但是相比之下,java是一種更“純粹”的面向物件程式設計語言。 2.1 用引用操縱物件 一切都視為物件,因此可採用單一固定的語法。儘管這一切都看作物件,但操縱的識別符號實際上是物件的一個“引用(reference)”。 java語言的一個特性:字串可以用帶引號的文字初始化。通常,

java程式設計思想》四版 2 一切都是物件 2 . 3 絕對不要清除物件

在大多數程式設計語言中,變數的“存在時間”(Lifetime)一直是程式設計師需要著重考慮的問題。變數應持 續多長的時間?如果想清除它,那麼何時進行?在變數存在時間上糾纏不清會造成大量的程式錯誤。在下面 的小節裡,將闡示Java 如何幫助我們完成所有清除工作

c++ primer 2 變數基本型別

幾個小問題: (1)c++語言是什麼時候檢查資料型別的?(這麼提問好像不合適,但是又不知道怎麼表達,先這樣吧) 一些語言,如smalltalk和python等,是在程式執行的時候檢查資料型別的;與之相反,c++是一種靜態資料型別語言,它的型別檢查發生在編譯時。 (2)i

《Python程式設計:從入門到實踐》2 變數簡單資料型別

第2章 變數和簡單資料型別 2-3 個性化的訊息 將使用者的姓名存到一個變數中,並向該使用者顯示一條訊息。顯示的訊息應非常簡單,如“Hello Eric, would you like to lear

java程式碼優化(一)——建立銷燬物件

用靜態工廠方法代替構造器 準備知識 自動裝箱:從基本資料型別轉換成包裝型別。 自動拆箱:從包裝型別轉換成基本資料型別。 包裝類: number(數字型別) Byte(byte) Short(short) Integer(int) Long(long) Dou