天天看點

java first head_Head First Java學習筆記

1.基本概念

1.1.工作方式

源代碼(.java)---編譯器(執行javac程式)---産生位元組碼(.class與平台無關)---JAVA虛拟機(JVM,讀取與執行位元組碼)

1.2.彙編語言是對基礎機器的少量抽象,C,BASIC,FORTRAN等是對彙編語言的一種抽象

1.3.類執行個體化的過程相當于建立了一個句柄

1.4.doStuff(c),一個圓句柄傳遞給一個本來期待shape句柄的函數,圓是shape的子類,是以doStuff()發給shape的消息,circle也能接受,原因是編譯器編譯代碼時并不知道自己要操作的準确類型是什麼,這種情況叫多形性,實作的方法叫叫動态綁定

1.5.使用者送出的資訊通過所有WEB伺服器均能支援的“通用網關接口”(CGI)會傳到伺服器

1.6.資料儲存地:

1.6.1.寄存器

1.6.2.堆棧(RAM,儲存句柄)

1.6.3.堆(RAM,儲存對象)

1.6.4.靜态存儲(RAM,static)

1.6.5.常數存儲(ROM)

1.6.6.非RAM存儲(另一台機器或磁盤,不依賴于程式是否運作)

1.7.執行個體變量數字預設值為0,BOOLEAN初始值為false,對象引用為null,局部變量沒有預設值,必須初始化

2.構造器與垃圾收集器

2.1.正在執行的方法位于棧頂,執行完被釋放掉

2.2.對象存在于堆中,執行個體變量存在于所屬對象中,局部變量和方法的參數的生命周期隻限于方法被放在棧上的這段期間,即所有局部變量存在于棧上的堆棧塊中

2.3.primitive主資料類型變量指boolean,    char, byte,short,int,long,float,double這8種

2.4.對象引用變量與primitive主資料類型變量都是放在棧上

2.5.方法的參數傳遞都是值傳遞,基本類型傳值,引用類型傳位址

2.6.記憶體分兩種,堆記憶體和棧記憶體

2.7.數組和對象在沒有引用變量指向它的時候,才變成垃圾,不能再被使用,但是仍然占着記憶體,在随後的一個不确定的時間被垃圾回收器釋放掉。這個也是java比較占記憶體的主要原因

2.8.堆和棧由JVM自帶的機制進行管理

2.8.執行個體變量存在于對象所屬的堆空間上,如果執行個體變量是個對象,則會在目前對象的堆空間中存入對象的引用變量,被引用的對象在被NEW的時候放在另一個堆空間中

2.9.記憶體配置設定政策:

靜态

2.10.無參構造函數是必須的(沒有建的時候系統提供,自己寫了構造函數的話則必須自寫無參構造函數)

2.11.執行NEW的指令是個重大事件,它會啟動構造函數連鎖反應,一直到Object這個類為止,建立子類,其繼承的父類也會被連鎖建立,建立對象時其構造函數被逐次放到堆棧塊,逐級調用直到最上面是Object類的構造函數

2.12.如果建立子類對象時,在子類的構造函數中沒有寫對父類構造函數的調用,則編譯器會自動幫我們加上super(),對super()的調用預設會加在第一行,自寫的話也必須保證在第一行

2.13.使用this()來從某個構造函數調用同一個類的另外一個構造函數,隻能用在構造函數中,且必須是第一行語句,super()與this()不能兼得

2.14.方法運作于堆棧

2.15.局部變量在方法執行時存活,方法執行完死掉,活着的時候狀态會被儲存

2.16.有3種方法可以釋放對象的引用

引用離開它的範圍,如函數中有執行個體化,函數執行結束後

引用被重新指派到其他對象上

引用被重新指派為null

對象的引用死掉後,該對象就等着垃圾處理器回收了

2.17.靜态方法直接從類調用,沒有對象的引用,抽象的類是不能被初始化的

2.18.可通過用私有的構造函數來限制非抽象類被初始化eg:Math

2.19.靜态方法不能調用非靜态的變量,因為靜态方法通過類名稱來調用,是以無法引用到該類的任何執行個體變量,因為靜态方法不知道堆上有哪些執行個體

2.20.靜态方法也不能調用非靜态方法,即使可以通過引用變量調用靜态方法,但靜态方法依然不知道是哪個對象引用所做的調用

2.21.同一類所有的執行個體共享一份靜态變量,即可以用靜态變量來統計某個類被建立執行個體的個數

2.22.靜态變量的預設值為該變量類型的預設值

2.23.JVM決定什麼時候加載類

2.24.final的類不能被繼承,final方法不能被覆寫,final變量不能被改變值

2.25.primitive資料類型與對應的包裝類型編譯器會自動進行轉換,即某處用到某種類型都可用其對應的類型替代

3.異常處理

3.1.編譯器會核對每件事,除了RuntimeException之外

3.2.判斷某個方法可能會抛出異常的方法是看該方法有沒有throws Exception,那麼其他方法在調用該方法時就要聲明try/catchl

3.3.try/catch塊種發生異常後,try後的語句不再執行,執行完catch後整個try/catch塊後接着執行

3.4.try塊失敗---catch塊---finally塊---其餘部分

try塊成功---finally---其餘部分

有return指令情況下流程會跳到finally然後再回到return指令

3.5.如果可能有多個異常,就要對應多個catch塊,但通常通過聲明多個異常的父類來代替聲明多個異常

3.6.在調用可能出現異常的方法時,該方法也可以抛出異常(throws Exception),那麼這個方法從堆棧上釋放掉,異常抛給調用它的方法,如果主方法也抛出異常,最終異常會抛給JVM,JVM無法處理死掉

3.7.内部類可以使用外部所有的方法與變量,就算是私用的也可以,内部類跟正常的類沒有差别還多了特殊的存取權,在外部類可以建立内部類的執行個體,如果要在外部類以外的程式初始内部執行個體,需要:

Outer ot=new Outer();

Outer.Inner in=ot.new Inner();

3.8.如果某類可序列化,則它的子類也可序列化

3.9.被标記為trasient的變量跳過執行個體化,靜态類不會被序列化,序列化的類需要實作Serializable接口

3.10.序列化:連結(此處FileOutputStream叫做連接配接串流)

ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(a.ser))

os.writeObject(one);

os.writeObject(two);

...

解序列化:連結,讀取的順序必須與吸入的順序相同

ObjectInputStream is=new ObjectInputStream(new FileInputStream(a.ser))

One one=(One)is.readObject();

Two two=(Two)is.readObject();

...

3.11.某類被序列化,則它的引用對象也會被序列化

3.12.緩沖區bufferedWriter

BufferedWriter bw=new BufferedWriter(new FileWriter(aFile))

bufferedWriter可以暫存一堆資料,等緩沖區滿時再寫入磁盤,這樣就減少了對磁盤的操作次數,提高了效率,因為每趟磁盤操作都比記憶體操作話費更多的時間,如果要強制緩沖區立即寫入,可調用bw.flush()這個方法

3.13.所有的流都是以下4個基本類的子類:

InputStream  Reader

OutputStream  Writer

InputStream和OutputStream及其子類處理位元組流,按ASCII編碼,主要用在處理二進制資料

字元流常用于文本

4.網絡與線程

4.1.Socket連接配接(用戶端對伺服器建立)

Socket a=new Socket(“11.1.45.234”,5000)

網頁伺服器(HTTP)端口是80,HTTPS:443 這是規定的标準

4.2.每個伺服器有65536個TCP端口(0-65535),0-1023都被保留給已知的特定服務

4.3.字元流與位元組流通過InputStreamReader,OutputStreamWriter來關聯,實際上是通過byte[]和String來關聯

4.4.從Socket得到的輸入流為位元組流

4.5.PrintWriter可作為字元資料與位元組間的轉換橋梁

4.6.伺服器對特定端口建立:

ServerSocket serverSock=new ServerSocket(4242);

伺服器會監聽4242這個端口

用戶端建立

伺服器建立與用戶端通信的新Socket

A.Socket sock=serverSock.accept();  (方法在使用者連接配接時傳回Socket)

伺服器會無限循環,每次循環會調用A方法,A檢測到用戶端連接配接了才會繼續往下執行

4.7.JAVA.LANG是被預設導入的

4.8.JAVA虛拟機會負責主線程的啟動以及垃圾收集所需的系統用線程

4.9.隻有多處理器才能同時處理好幾件事

4.10.線程調用start()方法後,進入待執行狀态,由虛拟機的線程排程機制來決定線程的狀态

4.11.  GUI:圖形使用者接口

4.12.建立新線程(2中方法)

A:實作Runnable接口

Runnable r=new MyRunnable();

Thread t=new Thread(r);

T.start();

B:用線程的子類覆寫掉run()方法

Class A extends Thread{

@Override

Void run(){......}

}

A a=new A(...)

A.start();

4.13.Thread.sleep()可以強制線程進入等待狀态直到過了設定時間為止,sleep()(可能跑出異常)可以讓所有線程都有機會運作

4.14.使用synchronized關鍵詞可以防止兩個線程同時進入同一對象的同一方法

4.15.每個對象有唯一的鎖和鑰匙,當使用同步化方法時,對象會在某個線程進入後鎖上,别的線程企圖進入就得等待

4.16.由于鎖機制,兩個線程在進入各自對象後睡覺醒來後通路對方的對象就都得處于等待狀态,造成死鎖

4.17.類本身也有鎖,比如靜态變量的保護

4.18.通過私有的構造函數和建立靜态執行個體可做出單例模式

5.資料結構

5.1.對象被system.out.println()時會調用toString()方法

5.2.幾乎所有以泛型寫的程式都與處理集合有關

5.3.public void takeThing(ArrayList  list)

=

public void takeThing(ArrayList extends Animal > list)

表示任何被聲明為Animal或Animal子類的ArrayList是合法的

public static > void sort(List list)

Comparable是個接口,以泛型的觀點,extend代表extends或implements

5.4.hashCode()使用雜湊算法對heap上的對象産生獨特的值,不同的對象有可能産生相同的值

6.包,jar存檔檔案和部署

6.1.javac -d 目标目錄  源檔案(.java)

可生成class檔案到指定目錄

6.2.jar工具可以從指令欄建立和執行JAR

7.分布式計算

7.1.目前接觸的大部分方法都是對運作在相同JAVA虛拟機的對象進行的,即調用方與被調用方在同一個堆上

7.2.JAVA遠端程式調用RMI(Remote Method Invocation)

7.3.遠端方法的參數必須是primitive或serializable類型,任何遠端方法的參數和傳回值都會被打包通過網絡傳送,這是通過序列化完成的

7.4.遠端接口要繼承Remote且要聲明異常,遠端實作要繼承UnicastRemote和實作遠端接口(最簡單的方式),産生stub和skeleton檔案,啟動遠端服務,遠端服務對象必須要向

RMI registry注冊,Naming.rebind()綁定

7.5.用戶端以Naming.lookup()查詢遠端服務

7.6.一般的servlet是繼承httpServlet的類并覆寫掉doGet(),doPost()方法

7.7.WEB伺服器會根據使用者請求來啟動并調用servlet上對應的方法,servlet可通過doGet()的響應參數取得輸出串流來組成響應的網頁

7.8.servlet是寫出帶有HTML輸出的類,JSP是寫出帶有JAVA程式的網頁,WEB伺服器最終會把JSP轉換成servlet,如果用servlet會出現一堆難以閱讀的print指令

7.9.String s=”0”;

For(int i=1;i<10;i++){

s=s+i;

}

最後會建立10個String,建立行的String時,會被放入String pool中,不受垃圾收集器管理,浪費記憶體

7.10.IDE:內建開發環境

7.11.需要外部類的執行個體才能取得内部類的執行個體

7.12.傳參的時候可以直接傳類的定義