隨筆 - 1  文章 - 1  trackbacks - 0
          <2008年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(1)

          隨筆檔案

          文章檔案

          搜索

          •  

          最新評論

          這是自己的一點筆記和一點初學方法建議,總結的是一些最基礎的、容易混淆或是理解錯誤的地方,適合像我一樣的菜鳥;有錯誤或是不正確的地方,希望大家不吝賜教
          CU真的是一個非常好的學習平臺,希望自己可以盡早地有能力為它的壯大與前進做點貢獻

          很難說現在類似這樣的認證還有多少說服力或者分量
          但是我覺得,有一個東西放在那里,給自己一個階段性的刺激與總結,也不失為一種學習方法
          所以自己初學java的定位就是,多讀幾本書,多讀些代碼,然后用這樣一個考試給自己一個暗示,可以算是初窺門徑了

          祝大家節日快樂


          ============筆記===============

          一.        聲明與訪問控制
          Javabean命名規則:set、get、boolean is、add/remove監聽器
          類的修飾符:默認、public、final、abstract、strictfp
          方法修飾符:默認、public、protected、private、final、abstract、static、strictfp、synchronized、native(不能有方法體)
          變量修飾符:volatile僅可用于實例變量
          接口修飾符:默認、public
          組合使用final與abstract、private與abstract、static與abstract是常見的錯誤
          局部(方法內)變量能攜帶的唯一修飾符是final,其他的修飾一律導致編譯錯誤
          方法參數(等價于局部變量)設定為final意味著方法不能修改它
          公共類中的protected可以被:1、同一包中的所有類(包級訪問權限)與2、自己的子類(無論在不在同一個包當中)看到。包外子類訪問protected域時,是通過繼承從父類繼承到了該域,而無法通過調用父類實例引用來訪問該域——.運算符將導致編譯錯誤;并且,包外子類繼承過protected成員之后,該成員在這個子類內實際上成為了私有的,因此只有該子類與其子類可以訪問
          抽象
          抽象方法必須顯示地聲明;抽象類可以包含非抽象方法;但倘使一個類中含有哪怕只是一個抽象方法,該類也必然是抽象的
          接口
          接口只能有抽象方法,隱式為public abstract;域全部是public static(隱式地),也即常量(而非實例變量);接口繼承的只能是接口;實現接口的抽象類可以選擇性地實現一部分方法,而被非抽象類實現時則必須實現全部方法,且全部方法顯示聲明為public
          Var-arg:作為參數,只能出現一次,且只能作為最后一名參數出現,表示收到的參數放入一個數組
          構造方法永遠不能有返回值;做了帶參構造器,則不會再有默認的無參構造器,此時調用默認構造器時會造成編譯錯誤
          變量:
          由小到大:byte——short——int——long,double大于float;數值類型全部是有符號的
          實例變量會得到默認值(包括類的對象實例,賦為null)
          局部變量在棧上,但如果變量是對象引用,該對象將會被創建在堆上。只有棧變量,沒有棧對象;局部變量使用前必須初始化先;將局部變量聲明為final是合法的,表示方法期間不能改變他的值;聲明與實例變量同名的局部變量是合法的,稱作隱藏
          聲明數組時指定長度是常見的錯誤
          沒有最終對象,只有最終引用:對象屬性是可修改的,但聲明為final的引用變量不可再修改引用的對象
          靜態
          Static用于變量與方法,這些變量和方法獨立于為類創建的任何實例:static的成員存在于實例被創建之前,無論類有多少實例,static的成員只有一套副本(所有static成員共享它們看到的一套值);方法本地內部類不能為static,內部類方法和實例變量不能為static,局部變量不能為static
          Enum
          枚舉不是簡單的字符或者整數,可以視為一個類
          枚舉可以1.聲明為獨立的類,2、在類中聲明為類成員;不可在方法中聲明;可用修飾符只有public與默認修飾符
          一旦聲明了一個枚舉,他就是不可擴展的:在運行時,無法創建而外的枚舉常量

          二、面向對象
          封裝
          思路:保護實例變量,提供公共的訪問器方法
          IS-A與HAS-A
          IS-A:通過繼承或實現而實現,可通過instanceof測試(只要在同一繼承樹之中,instanceof即可通過);HAS-A:一個類中的代碼有對另一個類實例的引用
          Overload 與 override
          Overload:重載時只有參數表可以做為標準,修飾符可以向寬松的方向修改
          Override:重寫時修飾符與返回值類型必須精確匹配
          也即:修改了修飾符與/或返回值類型,而參數表未加變動,既不是重寫也不是重載,產生編譯錯誤
          強制轉換
          向下強制轉換時,父類引用引用父類實例,使用子類顯示強轉可以通過編譯,但運行時發生cast異常(可以編譯通過);向上強轉時隱式與顯示皆可
          靜態
          總有這樣的錯誤:在main()中以各種形式(如在循環條件中)訪問非靜態實例變量。記住一點,運行main()的是類,而不是某一個類的實例
          靜態方法不能訪問實例(非靜態)變量/方法;靜態方法不可被重寫:嘗試以重寫的語法在子類中聲明一個方法會造成一個新方法的定義(可稱隱藏),調用時發生的是父類的static方法
          耦合講述了一個類了解另一個類的程度,內聚體現一個類設計目標明確、功能專一的程度

          三、賦值
          初始化的順序就是執行的順序
          一個占用int或更短長度的表達式,其結果總是int:byte+byte,int*short,short/byte
          數組聲明時不可加長度(編譯錯誤);注意索引范圍(運行時異常)
          初始化塊
          靜態塊執行一次,在類被加載時(main());當靜態塊中有錯誤時,編譯時不會報錯
          包裝器類、裝箱
          目的:使基類具備object類的特質;分類、轉換的方法
          每當有一個實例產生,實例塊被執行一次,在構造器super()之后被執行
          因此最終的順序:靜態塊——>super()——>實例塊——>構造器
          對于任何指定對象,finalize()至多只會被垃圾收集器調用一次;調用實際上能夠導致對象免于被刪除

          四、運算符
          對于復合賦值運算符,賦值號右側總是先被計算
          “+”的連接從左向右運行,操作對象中任一個為String則“+”身份為連接符;取消裝箱與連接一起作用
          ==與equals
          對于基類,數值相等時==的判斷將是true;若==兩邊類型不兼容編譯器將報錯;equals用于比較內容且不可用于基類,類型不兼容時可以編譯,得到false
          枚舉的相等性可用==與equal兩者驗證
          若對象的任何一個超類實現了某一個接口,我們就說該對象屬于這種接口:可以通過instanceof測試
          三目運算符連接時,順次檢查求值
          &&與||被稱作短路運算符,是因為他們的“測試優化”能力,&與|不具備這種特質;短路運算符視其前后為兩個獨立的表達式

          五、流程控制、異常與斷言
          開關語句:switch表達式的結果必須為char。Byte、short或可隱式提升為int的enum——總之就是能放進int容器的類型;case常量必須與開關里的類型一直,且必須是編譯時常量;在比int小的變量上使用switch且case常量大于變量范圍,導致編譯錯誤;從第一個匹配進入,沒有break時發生直落,default與其它case有著等同的地位(直落同樣會發生)
          do expression while();不要漏掉分號
          for循環提前結束的方法:return——跳轉回調用方法;break——跳轉至for后第一句;continue——跳出此次迭代;system.exit()——jvm關閉
          Try、catch與finally
          看見try時先尋找catch或者finally,孤立的try導致編譯錯誤
          將具體子類異常置于父類異常之上書寫catch(相反時編譯錯誤);兄弟異常順序隨意
          存在return時,finally先于return——finally必然被執行(除非在try外的異常導致編譯錯誤),因而在將異常傳回調用方法時,需要finally——它先執行,之后return
          在finally之后的語句將不被執行
          除非異常是運行時異常,方法聲明它拋出的異常(或者catch它),據此拋出的異常,屬于方法的公共接口

          六、字符串、IO、格式化與解析
          1)String、StringBuffer與StringBuilder
          String類被標識成了final,所有方法不可重寫
          String一旦創建,無法修改
          String s = new String(“abc”);//常規內存生成一個新的String對象,s引用了它;同時常量abc被放入String常量池
          StringBuilder的方法是非同步的
          考試討論的所有StringBuffer與StringBuilder方法都操作調用該方法的對象的值
          帶有兩個索引參數的方法,第一個參數從零0開始計數索引,第二個從1開始
          String沒有delete
          Replace(’char old’,’char new’);與replace(start, end, String);
          StringBuffer與StringBuilder返回String的方法:toString();
          文件導航與IO
          看到stream字樣的api,可知其與文件或io無甚關聯,可能是關于串行化的
          創建reader或者writer時,若文件不存在,則將自動創建它;但目錄不同,將會導致找不到文件/目錄異常
          串行化
          1、        僅能保存非靜態成員變量
          2、        保存的僅是變量的值,任何修飾符都無法保存
          3、        某些對象的值是瞬時的(thread、fileinputstream等),無法保存其狀態,必須用transient關鍵字標注;這樣的標注導致恢復時賦值為默認
          4、        要串行化的對象必須實現serializeable
          5、        要串行化的對象對應的類必須是public
          6、        欲串行化的類若has-a不能串行的成員(如未聲明為serializable或是一個私有成員),將會導致運行時錯誤
          一般的過程
          串行化:創建FileOutputStream,用ObjectOutputStream包裝,對對象進行writeObject()操作,close()
          反串行化:創建FielInputStream,用ObjectInputStream包裝,使用readObject()獲得Object類對象并執行強轉
          不能串行化的成員用transient標注,但反串行時這些成員將恢復默認值。對它們的保存引入了書寫private void write/read:注意第一句總是顯示調用defaulWrite/Read


          七、泛型與集合








          八、內部類
          一些固定的形式
          (1)靜態方法訪問非靜態內類:
                          方法為:
                          Outer myouter = new Outer();//這里的myouter是創建的外部類的對象
                          Outer.Inner myinner = myouter.new Inner();//myinner是內類的對象
                          然后再myinner.showName();//showName()是外類中的非靜態方法
          (2)非靜態方法訪問非靜態內類
                          直接創建該內部類的對象:new Inner().showName();
          (3)靜態方法訪問靜態內類:
                          也是直接創建該內部類的對象,即Inner myinner = new Inner()
          或Outer.Inner myinner = new Outer.Inner()
          靜態內部類相當于一個靜態成員,不可以訪問非靜態的對象,這里一定特別小心,多加注意
          匿名內部類存在的意義與應用的場合

          九、線程
          start()對我們唯一的保證:每個線程都將運行,每個線程都將運行至結束
          一旦start(),就永遠不能重新start()哪怕是它已經死去,否則導致運行時異常
          需要熟悉的方法:
          靜態yield(),大多數情況下使當前線程轉入可運行狀態,本意是使得具有相同優先級的其他線程獲得運行機會,這同樣無法得到保證
          靜態sleep(),轉入可運行狀態休眠一段時間,不放任何鎖;用法Thread.sleep(long),必須包圍在try-catch中
          join(),保證在調用join()的線程結束前,當前進程停止運行,也即當前執行線程內join()之后的語句保證在指定線程run()完之后運行
          靜態Thread.currentThread(),返回對當前執行線程的引用
          isAlive(),已經啟動,未結束run()
          start()的調用需要Thread的實例,不可以是runnable
          使一個實現runnable接口的類的實例啟動,可以做一個Thread,也可以直接調用run方法
          Runnable只有一個run方法,public void run();若沒有重寫這樣一個方法,將在聲明實現接口的地方報錯:未能實現該接口
          線程的啟動應調用start(),若直接調用run()則表示從當前正在運行的類調用一個普通的方法,run()進入當前調用棧,而不會啟動新的線程;重載的run()只能作為一般方法手動調用
          語法上,將線程傳遞給線程的構造器是合法的
          對線程進行setPriority()是沒有保證的。默認的優先級是5
          保護數據的操作:變量標識為private,同步訪問這些變量的方法
          在java中,每一個對象都有一個內置的鎖,鎖表現出作用的唯一情況是:對象具有同步方法代碼。當使用一個實例調用非靜態同步方法時,就會索取該實例的鎖
          對一個實例,某一時刻只能有一個線程鎖定它;拿到鎖的線程可以訪問該實例的任意同步方法/塊,其他線程可以任意訪問非同步方法
          為了減少同步對并發的影響,可以只將方法的一部分代碼放入同步塊中實現同步——同步塊應當指定這部分代碼執行時要鎖定的對象是誰:當指定this時可以寫成一個普通的同步方法的形式;對于靜態方法,在外圍聲明為synchronized或在block中使用LockTargetClass.class的形式指示鎖定對象,因為靜態成員只有一份拷貝,要將整個類所有靜態成員聲明為同步
          當對象的鎖被取走之后,其他試圖訪問同步方法的線程被阻塞在鎖上(進入阻塞狀態)。他們在某個特定的池等待對象的鎖被釋放,返回可運行狀態
          關于線程在同步上的互相阻塞:
          引用同一實例訪問非靜態同步方法的線程彼此阻塞
          訪問同一類中靜態方法的線程彼此阻塞——他們都在索取同一個Class實例的鎖
          訪問同一類靜態與非靜態同步方法的兩個線程不會彼此阻塞——一個在鎖定this,一個在鎖定class
          同步不同對象的兩個方法不會彼此阻塞
          保持鎖的方法:join(),sleep(),yield(),notify()
          放棄鎖的方法:wait()
          Access to static fields should be done from static synchronized methods. Access
          to non-static fields should be done from non-static synchronized methods
          線程安全類:不要把同步放在較高的級別上
          兩個線程互相等待對方拿到的鎖——死鎖
          Wait()、notify()等方法是Object類的方法,它們只能放入同步塊,這就保證了在獲得同步對象的鎖之前,不能在對象上調用這些方法
          每一個對象都可以有一個表,放置等待它信號的線程;一旦線程調用該對象的wait(),他們就進入這個列表之中,在目標對象調用notify()之前,這些線程什么都不做——也就是說,看到wait()但找不到notify(),則wait()之后的東西永遠不會發生(假如可以正確編譯的話)在wait時,線將程釋放鎖
          a waiting thread will not return to runnable when the lock is released, unless a notification occurs
          考慮:有時notify()可能會先于wait()而發生調用。這樣notify()不會再發生,而后開始的wait()等不到結果。所以在等待之前,應當檢查notify()是否已經發生。
          阻止線程運行總結:
          睡眠:睡眠指定的時間,醒來時是可運行狀態,也即不保證醒來就是運行狀態;sleep()是一個靜態方法,因此在不能有一種做法可以讓一個線程使另一個線程睡眠——當前運行線程的代碼看到sleep()時,即刻睡去
          等待:
          因為需要一個對象的鎖定而被阻塞

          ============一點建議===============

          初學的幾本書
          mcgraw hill的scjp5 guide。這本書總結了很多容易犯錯誤或者難以真正理解的地方,當然這一點跟它“考試輔導”的身份有著密切關聯,一些地方會專門為考試來講解。但它仍然是一本很好的初學手冊,順利地讀完并理解之后,就可以有比較充分的準備邁進java的大門了。要注意的是應當讀英文原版而不是中文版,除非你對自己閱讀邏輯混亂文不搭義的語句的能力充分自信,并且不在乎這樣那樣的翻譯錯誤
          o'reilly的java 1.5 tiger。配合tij來看吧,大家讀的tij大多都是3rd edition不是么
          java puzzlers。能夠全部弄清的話,很多概念就徹底理解了吧
          最后,自然是thinking in java。我讀了一遍,正準備重修一遍
          其他如java 線程、java io等等具體領域的轉本,不妨有一個全面的基礎之后有選擇地瀏覽

          要注意的地方
          我覺得java也好cpp也好,都要對體現語言特性的地方做到真正透徹的理解
          對于java,諸如初學最容易輕視的引用、初始化與聲明、值傳遞與引用傳遞、靜態成員等地方,都不要留下疑惑
          posted on 2007-05-11 15:45 滄佰 閱讀(175) 評論(1)  編輯  收藏

          FeedBack:
          # re: 轉載:一些JAVA筆記,對初學者有用 2008-06-02 18:03 夢回樓蘭
          還不錯,謝謝啦~~  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 渭南市| 宁津县| 乌审旗| 礼泉县| 宝坻区| 宁化县| 南陵县| 社旗县| 东丰县| 汉川市| 类乌齐县| 桐城市| 淳安县| 永安市| 南昌市| 巢湖市| 开远市| 浦县| 平江县| 湘乡市| 永新县| 广灵县| 南皮县| 留坝县| 会同县| 土默特右旗| 四会市| 太保市| 巴中市| 鄂伦春自治旗| 中超| 邵东县| 龙里县| 含山县| 濮阳县| 韩城市| 娱乐| 房山区| 吉木乃县| 宁德市| 象山县|