<<Thinking in Java>>從是一本好書, 總的來說這本書講的非常雜, 方方面面都有講到, 各個知識點延伸的也不錯. 但是一本容量如此之大的書挑不出一點瑕疵是不可能的, 并且作者本人的個人風格在本書中體現的比較重, 導致它在部分細節(jié)出現了一些問題, 如果鉆研的不是太深入的話其實大多無傷大雅, 因為閱讀本書最重要的是領會作者所想表達的編程思想. 但是研究完了JVM之后再來讀本書就會發(fā)現里面小毛小病有點多, 目前只找到這么多, 之后會再補充:
1. P96 構造器是靜態(tài)方法
? 原文是"即使沒有顯示地使用static關鍵詞, 構造器實際上也是靜態(tài)方法".
? 這個問題我在另一篇博文講到過, 構造器怎么想都不是靜態(tài)方法, 它是一種只在new或者反射時new instance中調用的特殊方法. 證明就是JVM會給構造器傳入一個this指針, 說明構造器是屬于該類的一個方法.
? 這里我想談談什么是靜態(tài)方法, 靜態(tài)方法雖然是在放在某一個類里面的(Java里面所有東西都在class里面), 但它和所屬類的關系僅僅是在加載時體現的, 換句話說, 拋開加載的時機不談, 靜態(tài)方法和靜態(tài)字段其實和這類沒半毛錢關系(好吧, 真要說關系的話還是有一點的, 如果是private的話只能本類的"東西"來調用, 這個"東西"可以是對象也可以是靜態(tài)的東西), 靜態(tài)方法應該有以下特點(純本人想法, 僅供參考):
靜態(tài)方法不屬于任何一個對象, 它是全局的, 在我眼中它更像是由JVM持有的方法(其實我也是在學JS的過程領悟到的, JS的全局是window, 那么Java的全局就是JVM啰).
-
因為不會像普通方法那樣隱性的傳入this指針, 所以靜態(tài)方法里面不能調用屬于該類的fields或方法.
結論: TIJ在胡說八道 = =
2. P143 private和final
? 原文: "類中所有的private方法都隱式的指定為是final的".
? 實際上這兩個關鍵字完全沒有關系, private指的是只有本類才能調用, final則是不可變(immutable), 反例也非常好找, 在子類中繼承final會報錯, 但是繼承private卻不會報錯(其實不是繼承, 子類和父類是兩個方法). 如果private是final的, 那么它也應該會報錯才對.
? final是不能被重寫, 可以被繼承的, private也是不能被重寫, 可以繼承, 但是繼承的方法子類訪問不到. 只有通過父類public的方法才能訪問到, 舉個例子:
public class Father {
private int a = 1;
public int getA(){
return A();
}
}
public class Son extends Father{
public static void main(String[] args) {
Father father = new Son();
System.out.println(father.getA());
}
}
可以看出, Son要想訪問Father類的私有字段, 需要通過公開方法去訪問, 也就是說子類對象是繼承了父類的私有字段和方法的.
? 題外話: 關于final有個非常實用的小技巧, 我是從<<重構>>中學到的, <<重構>>中談到一個引用最好職責單一, 不要重復賦值, 要是有一個引用前后干了不同的事情那么最好把它們拆開來, 不用前一個引用而是再寫個新引用. 那么要怎么判斷一個引用有沒有重復賦值呢? 非常簡單啦, 就是加個final關鍵詞, 如果改過了這個引用編譯器就會報錯.
3. 第14章 關于RTTI和反射
? 原文認為RTTI是一種運行時類型識別, Java的多態(tài)用的就是RTTI實現的, 而反射則是能在運行期獲得.class的類型信息. 這里道理說的都很對, 只是Sun從來沒有認為Java有RTTI這個說法. 具體多態(tài)是怎么實現的可以看我的這篇文章..
最后是一點點自己的感想, 對于本書的作者, 我是抱著敬仰之心的. 能把這么多內容組織好本身就證明了作者的功力(聽說Bruce Eckel的新書On Java8足足寫了1300多頁...). 寫文章本身就是一種設計的過程, 寫程序需要設計, 寫文章也需要設計. 寫多了博客才會發(fā)現自己的表達能力十分欠缺, 其實真正缺乏的正是怎么把內容組織好的能力, 所以說需要學習的東西還很多, 不僅僅是技術方面, 還有方方面面 = =.