1,static member
可使用該類對象的空引用來引用該類static member
SomeClass obj = null;
obj.staticMethod();
obj.staticData = 1;
用對象引用靜態成員是不被推薦的,但為什么不像C#那樣禁止掉呢?
2,多重繼承
面對從多個接口繼承而來的簽名相同的方法,子類似乎只能提供一份實現,這樣語義的正確性是如何保證的呢?C#可以在子類中為從多個接口繼承而來的簽名相同的方法各提供一份實現
3,局部類、匿名類、接口內部類
語言在設計方面提供的創新的語法設施,唯一的問題是不要濫用
4,混亂的數組
似乎違反了那句“裝蘋果的籃子不是裝水果的籃子”,在需要基類數組的地方可以傳遞子類數組,喪失了編譯期類型安全性,通過運行時異常來避免錯誤
5,求值順序
明確規定了從左至右,善莫大焉
6,作用域
局部變量、參數能夠屏蔽成員變量
局部變量不能與參數同名
更加局部的變量不能與外圍局部變量同名
善莫大焉
7,逗號表達式
沒有逗號表達式,for里面那個不算
8,break label
功能強大,代替flag,goto
9,異常
相對于返回錯誤代碼來說,異常就是那個層次的AOP
10,異常聲明與返回值的不同待遇
相同的是都不能做為overload的依據,不同的是override時,異常聲明可以被放寬為子類,返回值卻不能基于同樣的理由放寬為子類,即協變
11,類鎖與實例鎖
互不相干
12,服務端同步與客戶端同步
前者主要保護自己的內部數據,后者主要保證調用序列
13,main
Everything has a begin, has an end-------Matrix Revolution
我猜中了開頭,卻猜不到這結局----仙履奇緣
Java程序以main始,卻未必以main終,直到最后一個user線程退出;?假若main啟動了一個user線程,該線程又啟動了一個,又啟動了一個,則雖我之死,有子存焉;子又生孫,孫又生子;子又有子,子又有孫。子子孫孫,無窮匱也
先有雞還是先有蛋?人的起源,生命的起源到底如何?或許有一天人們追溯到極點,卻發現不過是JVM啟動了main,世界毀滅時,不過是JVM崩潰了
扯遠了,.Net的線程與此類似
14,J2SE 1.5的倒退
靜態引入 Static Import
格式化的輸出 Formatted Output
格式化的輸入 Formatted Input
不定參數 Varargs
簡直不敢相信,寧肯學C也不學C++
15,Proxy
當年C++中引入template,只是為了Generic Programming,卻無意中發現了其Generative Programming的強大功能;不知道Java中的Proxy最初的意圖是什么,卻引起了Generative Programming另外一種形式--AOP的風潮
16,ClassLoader
在程序中開個后門,某個類的字節碼從我的個人網站上下載,別被客戶發現,以后想起來就改改,呵呵
17,語言、庫、平臺,模糊的邊界
字符串連接操作符“+”,是語言的一部分還是庫的一部分?
序列化/反序列化時那個可被虛擬機調用的私有的方法,是語言的一部分還是庫的一部分?
SoftRefrence、WeakRefrence等被虛擬機用來處理對象引用這樣的核心語言特性的類,是語言的一部分還是庫的一部分?
Java不是平臺無關的,它本身就是個平臺;不是說它不好,只是和傳統的語言有這樣一些區別
18,@deprecated
比起XDoclet等工具,.Net的屬性等特性,它更早的觸動了Java的神經:注釋居然影響了編譯器的行為!總算發展出了帶有標注的Java
19,override的不同理念
Java/C#:只要訪問權限允許,就可以調用重寫的方法,不管子類對象構造出來沒有
C++:只要子類對象構造出來了,就可以調用重寫的方法,不管訪問權限
造成的后果就是:
Java/C#:在基類構造函數里調用方法,只要子類有權限覆寫,就會調到子類的實現
C++:在基類構造函數/析構函數里調用的方法永遠都是基類的實現,不會調到子類;在其它方法里面永遠都是調到子類的覆寫實現,不管是不是private
20,IO
字節是沒語義的,因此叫Stream
字符是有語義的,因此叫Reader與Writer
需要將沒語義的適配為有語義的,叫InputStreamReader,OutputStreamWriter
實用的,叫DataXXX,對象序列化的,叫ObjectXXX
21,java.io.File
放錯了地方,實際是文件系統的抽象,跟IO沒什么太大關系,應放到系統包里,跟Thread之類并列
22,Collections
一般的設計原則是子類重寫方法的前置條件應弱于父類方法,但Collection及其子類適時的沒有遵守這個原則,以此證明了任何原則都有適用范圍; Collection的設計目的是盡可能通用,而不是運行時的多態,你仍然需要選擇合適的具體的數據結構,盡管它有時只是通過Collection接口來引用
23,Iterator
不同于STL,Iterator提供了內部安全的Remove(),部分還提供了Add();但遍歷終歸是不安全的,又一次不同于STL,Iterator自己能感知外界變化,拋出異常來自我保護,而不是產生未定義行為
24,Timer(),Timer(true)
最常用的卻不是最方便的,不得不記住參數;可以用兩個創建方法,可以用兩個子類,就算用參數,也應該用枚舉代替布爾,噢,忘了1.5之前沒有枚舉,那就靜態常量吧,new Timer(Timer.DEAMON)和new Timer(true),哪個更清晰?
25,脆弱的private
除了序列化/反序列化時訪問權限被平臺破壞,在缺省安全設置下,Class.newInstance()也能夠構建ctor聲明為private的類的實例,帶來的效果就是,希望強迫客戶代碼使用IoC原則的開發者,可用放心的將bean的ctor聲明為private了