程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Thinking in Java 筆記,thinkingjava

Thinking in Java 筆記,thinkingjava

編輯:JAVA綜合教程

Thinking in Java 筆記,thinkingjava


  大二就買了這本書,如今再看這本書,看到了一些以前沒看的細節,也有了不同的體會。本文使用第4版,整理每章的筆記心得。老外的書有個特點,他會花費大量的文字去闡述一個概念,這比堆代碼強多了。

第 1 章 對象導論

1.1 抽象

  抽象是計算機最重要的概念之一。C 在解決問題時,主要是基於計算機的結構進行抽象,而不是基於所要解決的問題的結構。而 Java 則是針對問題進行建模,根據問題來描述問題,程序可以通過添加一個新類型的對象使自身適用於某個特定問題,程序員不會受限於任何特定類型的問題。

  對象具有狀態、行為和標識。純粹的面向對象程序設計的基本特性:

  • 萬物皆為對象:對象可以存儲數據(狀態),也能執行某些操作(行為)。理論上,可以抽取待解決問題中的任何概念化構建為對象。
  • 程序是對象的集合,它們通過發送消息告知彼此所要做的:其實就是調用特定對象的方法。
  • 每個對象都有自己和其他對象構成的存儲:通過現有對象生成新對象,繼承和組合。
  • 每個對象都擁有其類型:每個對象都是某個類的實例 。
  • 一類對象可以接收同樣的消息:多態,子類能夠替代父類完成某些調用。

1.2 類和對象

  每個對象都是某個類的實例,一個類實際上就是一個抽象數據類型,它描述了具有相同特性(成員)和行為(功能)的對象集合。程序員可以通過定義類來適應問題,而不是被迫使用現有的用來表示機器中的存儲單元的數據類型。根據需求添加新類型擴展編程語言,系統就像對待內置類型一樣驗證並管理它們。

  把對象看做是服務提供者好處:將問題分解為一系列對象的集合;提高對象的內聚性,每個對象都專注本職工作,就是高內聚性,還有個低耦合,解耦一般就用隊列實現;方便理解代碼和重用。

  面向對象的特點:封裝、繼承和多態。何為封裝?即隱藏對象的屬性和細節,僅對外公開接口,控制屬性的讀取和修改。訪問控制存在的原因:隔離與提供的服務無關的部分;分離並保護接口和實現。Java 中有四種訪問權限,分別是:

  • public:對任何人都可訪問 
  • private:只有類創建者和內部方法可訪問
  • protected:與 private 相當,區別是子類可訪問
  • 默認訪問權限:同一包內的類可相互訪問,不同包如同 private 一樣

1.3 代碼復用

  兩種方式,組合和繼承,組合靈活性比較高,相比於繼承耦合度低一些。如果要使用某個類提供的服務功能時,一般用組合,當要是使用類提供的接口時使用繼承。

  繼承,使用現有的類創建新類型。子類擁有父類的成員(public, protected)並且復制了父類的接口,也就是說,子類與父類具有相同的類型。子類有兩種方式改變自己的行為:添加新方法和覆蓋父類的方法。當添加新方法時,如果所有子類都需要,就可以把它抽取到父類中。

  Java 中,Object是所有類的直接或間接父類。單根繼承的好處有:所有對象具有共用接口,利於向後兼容;所有對象都具備某些功能,易於創建和參數傳遞;易於垃圾回收。

1.6 多態

  既然父類和子類是相同類型,那麼在運行時子類就能替換父類(向上轉型)來完成不同的功能,這就是多態。多態的體現是:方法的重載和覆蓋。編譯器(靜態分發,重載)和運行系統(JVM動態分發,覆蓋)會處理相關細節,保證程序正確的行為。

1.7 容器和泛型

  容器,就是Java中的數據結構了,不同的容器提供不同的接口和行為,對於某些操作具有不同的效率。在JDK 5 之前容器存儲的對象是Obejct,存儲對象必須向上轉型,會丟失其身份,當取出時需要向下轉型,可能會出錯,因為不知道之前放進去的是什麼類型的對象,因此,JDK5增加了泛型,明確指出容器可接收的對象類型。

1.8 對象的創建和生命周期、異常和並發

  Java 使用動態內存分配技術,使用關鍵詞 new 在堆上創建對象。使用垃圾回收器釋放對象占用的內存。

  Java 內置了異常的處理,而且強制使用。異常提供了一種從錯誤進行可靠恢復的途徑。

  並發控制好共享資源的訪問即可,Java提供了並發編程庫,有現成可用的並發數據結構。

1.9 Java與Internet

  網絡編程會涉及到很多知識,TCP/IP,多線程,IO模型等,要寫出高性能的Java程序,還是要下大工夫的,雖然大問題被JVM搞定了。

第 2 章 一切都是對象

2.1 對象

  Java 通過引用來操作對象,使用 new 創建對象。那麼對象被安置在哪個地方呢?計算中有5個地方可以存儲數據,分別是:

  • 寄存器:位於CPU內部,最快的存儲區,根據需求進行分配,不能直接控制
  • 堆棧:位於RAM,使用堆棧指針上下移動分配內存,速度僅次於寄存器,Java對象不在此,但引用在這裡。Java系統知道棧裡的元素確切生命周期
  • 堆:位於RAM,存放所有的 Java 對象,分配內存比較靈活,但代價是慢
  • 常量存儲:常量值通常放在程序代碼內部,或者放在 ROM 只讀存儲器中
  • 非RAM存儲:如將對象序列化到磁盤上,或者存在數據庫中

2.2 基本類型

  基本類型存儲值,並置於堆棧中,高效。Java 中基本類型的大小是固定的,不隨硬件架構的變化而變化。基本類型如下:

  • char:16-bit,2字節,Unicode字符,0 ~ 2^16-1,Character
  • byte:8 bits,1字節,-128 ~ 127,Byte
  • short:16 bits,2字節,-2^15 ~ 2^15-1,Short
  • int:32 bits,4字節,-2^31 ~ 2^31-1,Integer
  • long:64 bits,8字節,-2^63 ~ 2^63-1,Long
  • float:32 bits,4字節,IEEE754,Float
  • double:64 bits,4字節,IEEE754,Double
  • boolean:true/false,Boolean
  • void:Void

  所有數值均有正負號,JDK5的自動包裝功能,自動地將基本類型轉為包裝類型。

  高精度數字:BigInteger:支持任意精度的整數;BigDecimal:支持任意精度的定點數。

  數組也是對象,能存儲基本類型和引用類型,Java會確保數組被初始化。

2.3 作用域 scope

  Java 使用花括號定義作用域,局部變量在花括號結束時,生命周期就結束了,而對象不是如此,它能一直保存下去,Java通過垃圾回收器管理對象的內存。一般不會出現內存洩漏,但也不是絕對的。

2.4 類,字段,方法

  使用 class 關鍵字定義一個類,類擁有字段(成員變量)和方法,對於成員變量,即使沒進行初始化,Java也會保證它有一個默認值,引用類型默認為null,數字都默認為0,布爾默認false,char默認’\u0000’(null)。對於局部變量編譯器會強制進行初始化。

  方法,方法名和參數合起來稱為方法簽名,關於參數,在Java中只有值傳遞。Java消除了向前引用的問題,也就是同一個類中,成員變量和方法的先後順序可以隨意。

  static關鍵字可用來修飾字段,方法和類。修飾字段方法:表示屬於類,不用新建對象就可使用。一般是修飾內部類,此類與一般的類沒有差別。

2.5 注釋

  常用標簽和html如下:

  • @see:引用其他類,@see classname,@see fully-qualified-classnam#method-name
  • @author:作者信息
  • @version:版本信息
  • <pre>code</pre>:代碼
  • <ol><li>1<li>2</ol>:列表
第 3 章 操作符

3.1 優先級&賦值運算符

  從左到右先乘除後加減,當不確定時,使用括號明確標識即可。

  賦值運算符(=),對基本類型賦值就是把一個地方的內容復制到另一個地方,比如int a=b,就是把b的內容復制給a;對對象賦值只是使這個變量也指向該對象,比如String s = a,s和a指向同一個對象。將對象傳給方法時,也只是傳遞一個引用的值,或者說傳遞一個對象的別名。

3.2 算術、關系、邏輯運算符,直接常量

  加減乘除,取模,一元加、減操作符,自增,自減。

  == 作用於基本類型,比較值是否相等;作用於對象比較是否是同一個引用,比較對象使用equals,默認的equals比較引用,需要重寫。

  與(&&)、或(||)、非(!)生成一個布爾值,具有短路功能,即如果第一個表達式能確定整個表達式的結果,那麼就不會運算後面的表達式。

  直接常量,必須明確告訴編譯器常量類型,比如10F,10D,10L,0xFF。對於char、byte、short超過其最大范圍自動轉為int。

  指數計數法:float a = 1.39E-43F;表示1.39×e^-43,如果不加F編譯器默認會當做double處理,會提示類型轉換。

3.3 位操作符和移位操作符

  位操作符:

  • 與(&):同為1,輸出為1
  • 或(|):有1,輸出為1
  • 異或(^):不全為1,輸出為1
  • 非(~):取反

  移位操作符,只能用來處理整數,char、byte、short移位時自動轉為int:

  • 左移(<<):低位補0,相當於乘以2^n,n為移動位數
  • 右移(>>):使用符號位擴展,為正高位補0,為負高位補1,相當於除以2^n,n為移動位數
  • 無符號右移(>>>):高位用0擴展

  在進行移位時,比如int只有數值右端的低5位才有用,比如 16>>2 和 16>>34 相等,因為2^5=32,相當於對32取模。long類型就是低6位數字有效。

  這裡多說兩句,源碼中或進行移位時會經常看到(&0xFF),原因是什麼呢?

  一般我們會對字節byte進行操作,首先 0xFF 表示低8位(1字節),當對byte移位操作時,會自動轉成int,而Java中 int類型有32位,並且在計算機中數字使用有符號的二進制補碼表示。所以byte轉為int時會進行符號擴展,高位以符號位填充。如果byte為正數那麼其補碼與原碼相同,此時進不進行位與操作都無所謂,但是為負數時不同,比如byte a = -4;其轉為int在內部的表示就是11111111111111111111111111111100,這進行運算顯然是不正確的,有效位只有低八位,所以與0xFF位與運算,把高24位置0,運算結果就正確了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved