1. 程式人生 > >Java程式設計思想(第四版)筆記(一)

Java程式設計思想(第四版)筆記(一)


閒來無事,重讀一遍Java程式設計思想,有些自己感覺容易忘記的東西,記個筆記。

第2章 一切都是物件

2.2.2 基本型別

之所以特殊對待,是因為new將物件儲存在堆裡,故用new建立一個物件------特別是小的、簡單的變數,往往不是很有效。因此,對於這些型別,Java採取與C和C++相同的方法。也就是說,不用new來建立物件,而是建立一個並非是引用的“自動”變數。這個變數直接儲存“值”,並置於堆疊中,因此更加高效。

所有的數值型別都有正負號,所以不要去尋找無符號的數值型別。

boolean型別所佔儲存空間的大小沒有明確指定,僅定義為能夠區字面值true或false。

基本型別具有的包裝器類,使得可以在堆中建立一個非基本物件,用來表示對應的基本型別。

第3章 操作符

3.7 關係操作符

==和!=比較的是物件的引用,如果要比較兩個物件的實際內容是否相同,必須使用所有物件都適用的特殊方法equals()。但這個方法不適用於基本型別,基本型別直接使用==和!=即可。但equals()方法是Object類的方法,預設的還是比較引用,所以還要在需要比較內容的類中覆蓋equals()方法。

在Object類中,==是對地址的比較,equals()方法是對==的封裝,hashcode()方法是本地native方法,使用物件地址計算雜湊碼。所以,兩個Object物件的==、equals()和hashcode比較的結果應該是相同的,都是和原始地址相關的計算比較。

String類以及大部分基本型別的包裝類都已經對equals()和hashcode()方法進行了覆蓋,可直接使用它來比較內容是否相同。

3.16 Java沒有sizeof

在C和C++中,sizeof()操作符可以告訴你為資料項分配的位元組數,原因是為了“移植”。不同的資料型別在不同的機器上可能有不同的大小,所以在進行一些與儲存空間有關的運算時,程式設計師必須熟悉那些型別具體有多大。Java不需要,因為所有資料型別在所有機器中的大小都是相同的。

第4章 控制執行流程

4.3.3 逗號操作符

不同於逗號分隔符,逗號用作分隔符時用來分割函式的不同引數,Java裡唯一用到逗號操作符的地方就是for迴圈的控制表示式。在控制表示式的初始化和步進控制部分,可以使用一系列由逗號分隔的語句;而且那些語句均會獨立執行。

第5章 初始化與清理

5.2 方法過載

每個過載發方法都必須有一個獨一無二的引數型別列表。甚至引數型別順序的不同也足以區分兩個方法,但會使程式碼難以維護。不能以返回值區分過載方法,是因為有時你並不關心方法的返回值,比如僅僅寫個f();時,將無法區分呼叫哪一個。

5.4 this關鍵字

只能在方法內部使用,表示對“呼叫方法的那個物件”的引用。this的用法和其他物件引用並無不同。

static方法就是沒有this的方法,在static方法的內部不能呼叫非靜態方法,反過來倒是可以的。有人認為static方法不是面向物件的,因為它們的確具有全域性函式的語義,使用static方法時,由於不存在this,所以不是通過“向物件傳送訊息”的方式來完成的。的確,要是在程式碼中出現了大量的static方法,就該重新考慮自己的設計了。

5.5 清理:終結處理和垃圾回收

1.物件可能不被垃圾回收

2.垃圾回收並不等於“析構”

3.垃圾回收只與記憶體有關

使用垃圾回收器的唯一原因是為了回收程式不再使用的記憶體。所以對於與垃圾回收有關的任何行為來說(尤其是finalize()方法),也必須同記憶體及其回收有關。

當垃圾回收時, finalize()方法才會被呼叫,這就將對finalize()的需求限制到一種特殊情況,即通過某種建立物件方式以外的方式為物件分配了儲存空間。可Java中一切皆物件,那這種特殊情況又是什麼呢?看來之所以要有finalize,是由於在分配記憶體時可能採用了類似C語言中的做法,而非Java中的通常做法。這種情況主要發生在使用“本地方法”的情況下,本地方法是一種在Java中呼叫非Java程式碼的方式。本地方法目前只支援C和C++,但它們可以呼叫其他語言寫的程式碼,所以實際上可以呼叫任何程式碼。在非Java程式碼中,也許會呼叫C的malloc()函式系列來分配儲存空間,而且除非呼叫了free函式,否則儲存空間將得不到釋放,從而造成記憶體洩露。當然free()是C和C++中 的函式,所以需要在finalize()中用本地方法呼叫它。所以,finalize()不是進行普通的清理工作的合適場所。

無論是“垃圾回收”還是“終結”,都不保證一定會發生。如果Java虛擬機器並未面臨記憶體耗盡的情形,它是不會浪費時間去執行垃圾回收以恢復記憶體的。

5.7 初始化順序

類中初始化順序:父類靜態成員,子類靜態成員,父類構造方法,子類構造方法

第6章 訪問許可權控制

訪問許可權控制的等級,從最大到最小許可權依次為:public、protected、包訪問許可權(預設)和private。

6.1 包:庫單元

當編寫一個Java原始檔時,此檔案通常被稱為編譯單元。每個編譯單元都必須有一個字尾名.java,而在編譯單元內部可以有一個public類,該類的名稱必須與檔案的名稱相同(包括大小寫)。每個編譯單元只能有一個public類,否則編譯器就不會接受。如果在該編譯單元中還有其他的類的話,那麼在包之外的世界是無法看見這些類的,這是因為它們不是public類,而且它們主要用來為主public類提供支援。

當編譯一個.java檔案時,在.java檔案中的每個類都會有一個輸出檔案,而該輸出檔案的名稱與.java檔案中的每個類的名稱相同,只是多了一個字尾名.class。因此,在編譯少量.java檔案之後,會得到大量的.class檔案。

Java直譯器的執行過程如下:首先,找出環境變數classpath。classpath包含一個或多個目錄,用作查詢.class檔案的跟目錄。從跟目錄開始,直譯器獲取包的名稱並將每個句點替換成斜槓,以從classpath根中產生一個路徑名稱。得到的路徑會與classpath中的各個不同的項相連線,直譯器就在這些目錄中查詢與你所要建立的類名稱相關的.class檔案。

按照慣例,package名稱的第一部分是類的建立者的反順序的Internet域名,這樣便是獨一無二的。比如,某域名為blog.sina.com,則包名可為com.sina.blog.*。

Java可執行程式是一組可以打包並壓縮為一個Java文件檔案的.class檔案。Java直譯器負責這些檔案的查詢、裝載和解釋。