Thinking in java讀書筆記資料_第1頁(yè)
Thinking in java讀書筆記資料_第2頁(yè)
Thinking in java讀書筆記資料_第3頁(yè)
Thinking in java讀書筆記資料_第4頁(yè)
Thinking in java讀書筆記資料_第5頁(yè)
已閱讀5頁(yè),還剩36頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Thinkinginjava讀書筆t己

第一章對(duì)象導(dǎo)論

1.因?yàn)轭惷枋隽司哂邢嗤卣鳎〝?shù)據(jù)元素、靜態(tài))和行為(功能、動(dòng)態(tài))的對(duì)象集

合。public表示緊隨其后的元素對(duì)任何人都是可用的,而private這個(gè)關(guān)鍵字表示除類

型創(chuàng)建者和類型的內(nèi)部方法之外的任何人都不能訪問(wèn)的元素。Private就像你與客戶端

程序之前的一堵破墻,如果有人試圖訪問(wèn)private成員,就會(huì)在編譯時(shí)得到錯(cuò)誤信息。

篇protected關(guān)鍵字與private作用相當(dāng),差別僅在于繼承的類可以訪問(wèn)protected成

員,但是不能訪問(wèn)private成員。java中還有包訪問(wèn)權(quán)限。

2.在使用對(duì)象時(shí),最關(guān)鍵的問(wèn)題之一便是它們的生成和銷毀方式。每個(gè)對(duì)象為了生存

都需要資源,尤其是內(nèi)存。在堆棧中創(chuàng)建存儲(chǔ)空間和釋放存儲(chǔ)空間通常各需要一條匯

編指令即可,分別對(duì)應(yīng)將棧頂指針向下移動(dòng)和將棧頂指針向上移動(dòng)。創(chuàng)建堆存儲(chǔ)空間

的時(shí)間依賴于存儲(chǔ)機(jī)制的設(shè)計(jì)。

第二章一切都是對(duì)象

2.1用弓I用操縱對(duì)象(用地址指針操縱對(duì)象)

1.操縱的標(biāo)識(shí)符實(shí)際上是對(duì)象的一個(gè)“引用"(reference)?;蛘呓小暗刂贰?,句柄的東

西。

2.你擁有一個(gè)引用,并不一定需要有一個(gè)對(duì)象與它關(guān)聯(lián)。

如:Strings;

如果向s發(fā)送一個(gè)消息,就會(huì)返回一個(gè)運(yùn)行時(shí)錯(cuò)誤。一種安全的做法就是:創(chuàng)建一

個(gè)引用的同時(shí)便進(jìn)行初始化(強(qiáng)烈建議)。如:Strings=newString("");

2.2必須由你創(chuàng)建所有對(duì)象。

2.2.1存儲(chǔ)到什么地方

1)寄存器。

2)棧。位于通用RAM(隨機(jī)訪問(wèn)存儲(chǔ)器):一級(jí)cache,二級(jí)cache.雖然某些JAVA

數(shù)據(jù)存儲(chǔ)在堆棧中——特別是對(duì)象引用,但是JAVA對(duì)象不存儲(chǔ)其中。

3)堆(heap)o一種通用性的內(nèi)存池(也存在于RAM中),用于存放所有的JAVA

對(duì)象(對(duì)象本身)。堆不同于堆棧的好處是:編譯器不需要知道要從堆里分配多

少存儲(chǔ)區(qū)域,也不必知道存儲(chǔ)的數(shù)據(jù)在堆里存活多長(zhǎng)時(shí)間。因此,在堆里分配存

儲(chǔ)有很大的靈活性。當(dāng)你需要?jiǎng)?chuàng)建一個(gè)對(duì)象的時(shí)候,只需要new寫一行簡(jiǎn)單的代

碼,當(dāng)執(zhí)行這行代碼時(shí),會(huì)自動(dòng)在堆里進(jìn)行存儲(chǔ)分配。當(dāng)然,為這種靈活性必須

要付出相應(yīng)的代價(jià)-用堆進(jìn)行存儲(chǔ)分配比用棧進(jìn)行存儲(chǔ)存儲(chǔ)需要更多的時(shí)間。

4)靜態(tài)存儲(chǔ)(staticstorage)□這里的“靜態(tài)”是指“在固定的位置”。靜態(tài)存儲(chǔ)里存放

程序運(yùn)行時(shí)一直存在的數(shù)據(jù)。你可用關(guān)鍵字static來(lái)標(biāo)識(shí)一個(gè)對(duì)象的特定元素是靜

態(tài)的,但JAVA對(duì)象本身從來(lái)不會(huì)存放在靜態(tài)存儲(chǔ)空間里。

5)常量存儲(chǔ)(constantstorage)。常量值(final)程序代碼內(nèi)部,這樣做是安全的,

因?yàn)樗鼈冇肋h(yuǎn)不會(huì)被改變。有時(shí),在嵌入式系統(tǒng)中,常量本身會(huì)和其他部分分割

離開(kāi),所以在這種情況下,可以選擇將其放在ROM中(從硬盤加載源代碼)

6)非RAM存儲(chǔ)。如果數(shù)據(jù)完全存活于程序之外,那么它可以不受程序的任何控制,

在程序沒(méi)有運(yùn)行時(shí)也可以存在。在流對(duì)象中,對(duì)象轉(zhuǎn)化成字節(jié)流。通常被發(fā)送給

另外一臺(tái)機(jī)器。在“持久化對(duì)象“中,對(duì)象被存放于磁盤上。

就速度來(lái)說(shuō),有如下關(guān)系:

寄存器(堆棧<堆<其他

2.2.2特例:基本類型

基本類型不用new來(lái)創(chuàng)建變量,而是創(chuàng)建一個(gè)并非是引用的”自動(dòng)“變量。這個(gè)

變量直接存儲(chǔ)”值“,并置于棧中,因此更加高效。這里僅指八種基本類型(長(zhǎng)度固

定)。

Java語(yǔ)言提供了八種基本類型。六種數(shù)字類型(四個(gè)整數(shù)型,兩個(gè)浮點(diǎn)型),一種字

符類型,還有一種布爾型。

1、整數(shù):包括int,short,byte,long,初始值為0

2、浮點(diǎn)型:float,double,初始值為0.0

3、字符:char,初始值為空格,即”",如果輸出,在Console上是看不到效果的。

4、布爾:boolean,初始值為false。

基本型別大小最小值最大值

boolean———

char16-bitUnicode0Unicode2八16-1

byte8-bit-128+127

short16-bit-2*15+2~15-1

int32-bit-2*31+2'31-1

long64-bit-2*63+2*63-1

float32-bitIEEE754IEEE754

double64-bitIEEE754IEEE754

void

注意:表格里的人代表的是次方;

java米用unicode,2個(gè)字節(jié)來(lái)表示一個(gè)字符。

所有數(shù)值類型都有正負(fù)號(hào)。

byte(8bit)<char,short(16bit)<int(32bit)

基本類型具有包裝類,使得可以在堆中創(chuàng)建一個(gè)非基本對(duì)象。用來(lái)表示基本類型。

charc='x';〃存放在棧

Characterch=newCharacter('x');

高精度數(shù)字

Java提供了兩個(gè)高精度計(jì)算的類:Biginteger和BigDecimaL

Biginteger支持任意精度的整數(shù)。

BigDecimal支持任何精度的定點(diǎn)數(shù)。

2.2.3java中的數(shù)組

java確保數(shù)組會(huì)被初始化,而且不能在它的范圍之外被訪問(wèn)。是以每個(gè)數(shù)組上少量的

內(nèi)存開(kāi)銷及運(yùn)行時(shí)的下標(biāo)檢查為代價(jià)的。

創(chuàng)建一個(gè)數(shù)組對(duì)象時(shí),實(shí)際上是創(chuàng)建了一個(gè)引用數(shù)組,一旦Java看到null。就知道這

個(gè)引用還沒(méi)有指向某個(gè)對(duì)象。在使用任何引用前,必須為其指定一個(gè)對(duì)象;如果試圖

使用一個(gè)還是null的引用,在運(yùn)行時(shí)將會(huì)報(bào)錯(cuò)。

2.3永遠(yuǎn)不需要銷毀對(duì)象

2.3.1作用域:決定生命周期

作用域決定了在其內(nèi)定義的變量名的可見(jiàn)性和生命周期。

intx=12;

intx=96;〃報(bào)錯(cuò)。不同于java。

}

1

2.3.2對(duì)象的作用域〃存活于作用域之外

java對(duì)象不具備和基本類型一樣的生命周期。當(dāng)用new創(chuàng)建一個(gè)Java對(duì)象時(shí),它可以

存活于作用域之外。

Java有一個(gè)垃圾回收器,用來(lái)監(jiān)視用new創(chuàng)建的所有對(duì)象。

2.4創(chuàng)建新的數(shù)據(jù)類型:類

5.4.1字段和方法

一旦定義了一個(gè)類(在java中你所做的全部工作就是定義類,產(chǎn)生那些類的對(duì)象,以

及發(fā)送消息給這些對(duì)象),就可以在類中設(shè)置兩種類型的元素:字段(有時(shí)被稱作數(shù)

據(jù)成員)和方法(有時(shí)被稱為成員函數(shù))

基本成員默認(rèn)值

若基本數(shù)據(jù)類型作為類成員的時(shí)候,即使沒(méi)有進(jìn)行初始化。java也會(huì)給定默認(rèn)的初始

值。默認(rèn)是如下所示:

booleanfalse

char7uoooo*(null)

byte(byte)O

short(short)O

int0

long0L

floatO.Of

doubleO.Od

當(dāng)變量作為作為類成員使用時(shí),java才確保給定其初始值,防止程序運(yùn)行時(shí)錯(cuò)誤。

但是這些初始值對(duì)你的程序來(lái)說(shuō)是不正確的。所以必須明確指定初始值。然而以上所

訴并不適用于“局部”變量(即:非某個(gè)類的字段)。因此在某個(gè)方法中定義inti;那么變

量i可能得到的是任一值。不會(huì)被初始化為0。所以使用前先付一個(gè)適當(dāng)?shù)闹?。如果?/p>

記了,java會(huì)在編譯時(shí)返回一個(gè)錯(cuò)誤。告訴你此變量沒(méi)有初始化。在類中定義對(duì)象的

引用時(shí),如果沒(méi)有給定初始化值,此引用會(huì)默認(rèn)為null值。

也就是說(shuō)在java中基本類型的默認(rèn)值是0,引用類型會(huì)默認(rèn)為nulL

注意:只認(rèn)類的成員才能初始化。對(duì)局部變量那個(gè)要顯示初始化。

2.5方法、參數(shù)和返回值

intx=a.f();〃向?qū)ο骯發(fā)送f()消息。

2.5.1參數(shù)列表

2.6構(gòu)建一個(gè)java程序

static關(guān)鍵字:兩種方法調(diào)用類方法和類數(shù)據(jù)。(最好是用類名直接引用,在某

些情況下它為編譯器進(jìn)行優(yōu)化提供了更好的機(jī)會(huì))當(dāng)創(chuàng)建類時(shí),就是在描述那個(gè)類的

對(duì)象的外觀與行為。當(dāng)聲明一個(gè)事物是static時(shí),就意味著這個(gè)域或方法不會(huì)與包含

它的那個(gè)類的任何對(duì)象實(shí)例關(guān)聯(lián)在一起。

2.7注釋和嵌入式文檔

javadoc便是用于提取注釋的工具。

2.7.1語(yǔ)法

三種類型的注釋文檔:類,域和方法。

/*Aclasscomment*/類注釋

publicclassDocumentation1

/**Afieldcomment7域注釋

publicinti;

/**Amethodcomment*/方法注釋

publicvoidf(){}

}

javadoc只能為public(公共)和protected成員進(jìn)行文檔注釋。

可以通過(guò)-private進(jìn)行標(biāo)記,以便把private成員的注釋也包括在內(nèi)。

第三章操作符

1.操作符接受一個(gè)或多個(gè)參數(shù),并生成一個(gè)新值。Java中幾乎所有的操作符都只能操

作“基本類型"。例外的操作符是“="、和"!=”,這些操作符能操作所有

的對(duì)象。除此之外,String類支持“+”和“+=”。

2.賦值使用操作符“=”。它的意思是“取右邊的值(即右值),把它復(fù)制給左邊(即

左值)。對(duì)一個(gè)對(duì)象進(jìn)行賦值時(shí),我們真正操作的是對(duì)對(duì)象的引用。通過(guò)Random類

的對(duì)象,傳遞給nextlnt。的參數(shù)設(shè)置了所產(chǎn)生的隨機(jī)數(shù)的上限,而其下限為0。比較內(nèi)

容相等:1)對(duì)于對(duì)象,使用的是equals。。2)對(duì)于基本類型,使用==和!=。而如果

對(duì)于對(duì)象使用==和!=比較的是對(duì)象的引用。

3.==andequal?

inta=3,b=3;

Integeri=newInteger(3);

Integerm=newInteger(3);

System.out.println(i==m);//false(1)

System.out.println(a==i);//true(2)

//inta=b=3;〃在java中會(huì)編譯報(bào)錯(cuò)

System.out.println(a==b);//true(3)

Stringsi="Monday";

Strings2="Monday";

System.out.println(s1==s2);//true(4)比較引用,因?yàn)槭窃诔A繀^(qū)分配。

System.out.println(sl.equals(s2));//true(5)

Stringsll="Monday";

Strings22=newString("Monday");

System.out.println(sll==s22);//false(6)

System.out.println(s11.equals(s22));//true(7)

1.(1)說(shuō)明new方法在線程區(qū)變量中分配內(nèi)存。與(2)比較,

inta=3;

intb=3;

編譯器先處理inta=3;首先它會(huì)在棧中創(chuàng)建一個(gè)變量為a的引用,然后查找棧中是否

有3這個(gè)值,如果沒(méi)找到,就將3存放進(jìn)來(lái),然后將a指向3。接著處理intb=3;在

創(chuàng)建完b的引用變量后,因?yàn)樵跅V幸呀?jīng)有3這個(gè)值,便將b直接指向3。這樣,就

出現(xiàn)了a與b同時(shí)均指向3的情況。這時(shí),如果再令a=4;那么編譯器會(huì)重新搜索棧

中是否有4值,如果沒(méi)有,則將4存放進(jìn)來(lái),并令a指向4;如果已經(jīng)有了,則直接將

a指向這個(gè)地址。因此a值的改變不會(huì)影響到b的值。要注意這種數(shù)據(jù)的共享與兩個(gè)

對(duì)象的引用同時(shí)指向一個(gè)對(duì)象的這種共享是不同的,因?yàn)檫@種情況a的修改并不會(huì)影

響到b,它是由編譯器完成的,它有利于節(jié)省空間。而一個(gè)對(duì)象引用變量修改了這個(gè)對(duì)

象的內(nèi)部狀態(tài),會(huì)影響到另一個(gè)對(duì)象引用變量。

String是一個(gè)特殊的包裝類數(shù)據(jù)??梢杂茫?/p>

Stringstr=newString("abc");

Stringstr="abc";

兩種的形式來(lái)創(chuàng)建,第一種是用new()來(lái)新建對(duì)象的,它會(huì)在存放于堆中。每調(diào)用一

次就會(huì)創(chuàng)建一個(gè)新的對(duì)象。

->Stringstr=newString("abc");自己補(bǔ)充:應(yīng)該說(shuō)有會(huì)產(chǎn)生兩個(gè)對(duì)象,一個(gè)為new

String(“abc")的實(shí)體對(duì)象放到內(nèi)存堆中,一個(gè)為堆棧對(duì)象str也就是類實(shí)例對(duì)象的引用對(duì)

象。

而第二種(Stringstr="abc";)是先在棧中創(chuàng)建一個(gè)對(duì)String類的對(duì)象弓|用變量str,然后查找棧

中有沒(méi)有存放"abc",如果沒(méi)有,則將"abc"存放進(jìn)棧,并令str指向“abc”,如果已經(jīng)有“abc”則直

接令str指向“abc”。

比較類里面的數(shù)值是否相等時(shí),用equals。方法;當(dāng)測(cè)試兩個(gè)包裝類的引用是否指向同一個(gè)對(duì)象

時(shí),用==,下面用例子說(shuō)明上面的理論。

Stringstr1="abc";

Stringstr2="abc";

System.out.println(str1==str2);//true

可以看出str1和str2是指向同一個(gè)對(duì)象的。

Stringstr1=newString("abc");

Stringstr2=newString("abc");

System.out.println(str1==str2);//false

用new的方式是生成不同的對(duì)象。每一次生成一個(gè)。

因此用第二種方式(Stringstr="abc";)創(chuàng)建多個(gè)”abc”字符串,在內(nèi)存中其實(shí)只存在一

個(gè)對(duì)象而已.這種寫法有利與節(jié)省內(nèi)存空間.同時(shí)它可以在一定程度上提高程序的運(yùn)行

速度,因?yàn)镴VM會(huì)自動(dòng)根據(jù)棧中數(shù)據(jù)的實(shí)際情況來(lái)決定是否有必要?jiǎng)?chuàng)建新對(duì)象。而對(duì)

于Stringstr=newString("abc");的代碼,則一概在堆中創(chuàng)建新對(duì)象,而不管其字符串

值是否相等,是否有必要?jiǎng)?chuàng)建新對(duì)象,從而加重了程序的負(fù)擔(dān)。

另一方面,要注意:我們?cè)谑褂弥T如Stringstr="abc";的格式定義類時(shí),總是想當(dāng)然

地認(rèn)為,創(chuàng)建了String類的對(duì)象str。擔(dān)心陷阱!對(duì)象可能并沒(méi)有被創(chuàng)建!而可能只是

指向一個(gè)先前已經(jīng)創(chuàng)建的對(duì)象。只有通過(guò)new()方法才能保證每次都創(chuàng)建一個(gè)新的對(duì)

象。由于String類的immutable性質(zhì),當(dāng)String變量需要經(jīng)常變換其值時(shí),應(yīng)該考慮

使用StringBuffer類(線程安全,很多方法是syncronized的,但在jdk7以上,編譯器

會(huì)自動(dòng)優(yōu)化),以提高程序效率。

4.移位操作符:“有符號(hào)'右移位(?)操作符使用"符號(hào)擴(kuò)展":若符號(hào)為正,則在

高位插入0,若符號(hào)為負(fù),則在高位插入1。Java中增加了一種“無(wú)符號(hào)”右移位操作

符(>>>),它使用“零擴(kuò)展”:無(wú)論正負(fù),都在高位插入0。如果對(duì)char,byte或者

short進(jìn)行移位,那么在移位進(jìn)行之前,它們會(huì)被轉(zhuǎn)換為int類型。

5Java不會(huì)自動(dòng)地將int類型轉(zhuǎn)換為bool類型,所以在編譯時(shí)會(huì)拋出一個(gè)編譯時(shí)錯(cuò)

、口

第四章控制流程

4.1break和continue

break用于強(qiáng)行退出循環(huán),不執(zhí)行循環(huán)中剩余的語(yǔ)句。而continue則停止執(zhí)行當(dāng)前的

迭代,然后退回循環(huán)起始處,開(kāi)始下一次迭代。

同樣的規(guī)則適合whileo

1)一般的continue會(huì)退回最內(nèi)層循環(huán)的開(kāi)頭(頂部),并繼續(xù)執(zhí)行。

2)帶標(biāo)簽的continue會(huì)達(dá)到標(biāo)簽的位置,并重新進(jìn)入緊接在那個(gè)標(biāo)簽后面

的循環(huán)。

3)一般的break會(huì)中斷并跳出當(dāng)前循環(huán)。

4)帶標(biāo)簽的break會(huì)中斷并跳出標(biāo)簽所指的循環(huán)。

4.2goto

標(biāo)簽是后面跟有冒號(hào)的標(biāo)識(shí)符,如:label:。Java中的break和continue同goto使用

了標(biāo)簽機(jī)制。

4.3其他

l.return關(guān)鍵字有兩方面的用途:一方面指定一個(gè)方法返回什么值(假設(shè)它沒(méi)有void

返回值),另一方面它會(huì)導(dǎo)致當(dāng)前的方法退出,并返回那個(gè)值。

2.switch是一種選擇語(yǔ)句。根據(jù)整數(shù)(int或char類型)表達(dá)式的值,switch語(yǔ)句可以

從一系列代碼中選出一段去執(zhí)行。

第五章初始化與清理

初始化和清理正是涉及安全的兩個(gè)問(wèn)題。C++中采用構(gòu)造器和析構(gòu)函數(shù)來(lái)實(shí)現(xiàn)。

Java通過(guò)構(gòu)造器和“垃圾回收”來(lái)實(shí)現(xiàn)。

5」初始化順序

5.1.1對(duì)于單個(gè)類

對(duì)于靜態(tài)變量、靜態(tài)初始化塊、變量、初始化塊、構(gòu)造器,它們的初始化順序依次是

(靜態(tài)變量、靜態(tài)初始化塊)>(變量、初始化塊)〉構(gòu)造器。

我們也可以通過(guò)下面的測(cè)試代碼來(lái)驗(yàn)證這一點(diǎn):

publicclassInitialOrderTest{

〃靜態(tài)變量

publicstaticStringstaticField="靜態(tài)變量";

//變量

publicStringfield="變量";

//靜態(tài)初始化塊

static{

System.out.println(staticField);

System.out.println("靜態(tài)初始化塊");

}

//初始化塊

(

System.out.println(field);

System,out.printin("初始化塊");

}

〃構(gòu)造器

publicInitialOrderTest(){

System.out.println("構(gòu)造器”);

}

publicstaticvoidmain(String[]args){

newInitialOrderTest();

}

}

運(yùn)行以上代碼,我們會(huì)得到如下的輸出結(jié)果:

1.靜態(tài)變量

2.靜態(tài)初始化塊

3.變量

4.初始化塊

5.構(gòu)造器

5.1.2對(duì)于有繼承關(guān)系的類

classParent{

//靜態(tài)變量

publicstaticStringp_StaticField="父類一靜態(tài)變量”;

〃變量

publicStringp_Field="父類一變量";

protectedinti=9;

protectedintj=0;

//靜態(tài)初始化塊

static{

System.out.println(p_StaticField);

System.out.println,'父類-靜態(tài)初始化塊)

)

//初始化塊

(

System.out.println(p_Field);

System.out.println("殳類--初始化塊");

)

//構(gòu)造器

publicParent(){

System.out.println("父類-構(gòu)造器)

System.out.println("i="+i+",j="+j);

j=20;

publicclassSubClassextendsParent{

//靜態(tài)變量

publicstaticStrings_StaticField="子類--靜態(tài)變量";

〃變量

publicStrings_Field="子類一變量";

//靜態(tài)初始化戰(zhàn)

static{

System.out.println(s_StaticField);

System.out.println,'字類-靜態(tài)初詔化塊");

)

//初始化塊

(

System.out.println(s_Field);

System.out.printing子類--初始化塊");

)

//構(gòu)造器

publicSubClass(){

System.out.printin("子類一構(gòu)造器");

System.out.println("i="+i+",j="+j);

)

//程序入口

publicstaticvoidmain(String[]args){

System.out.printing子類main方法");

newSubClass();

)

)

運(yùn)行一下上面的代碼,結(jié)果馬上呈現(xiàn)在我們的眼前:

父類--靜態(tài)變量

父類--靜態(tài)初始化塊

子類--靜態(tài)變量

子類-靜態(tài)初始化塊

子類main方法

父類-變量

父類-初始化塊

父類--構(gòu)造器

i=9,j=0

子類--變量

子類--初始化塊

子類-構(gòu)造器

i=9,j=20

現(xiàn)在,結(jié)果已經(jīng)不言自明了。子類的靜態(tài)變量和靜態(tài)初始化塊的初始化是在父類的變量、初始化

塊和構(gòu)造器初始化之前就完成了。

靜態(tài)變量、靜態(tài)初始化塊,變量、初始化塊初始化了順序取決于它們?cè)陬愔谐霈F(xiàn)的先后順序。

執(zhí)行過(guò)程分析

⑴訪問(wèn)SubClass.main。,(這是一個(gè)static方法),于是裝載器就會(huì)為你尋找已經(jīng)編譯的SubClass

類的代碼(也就是SubClass.class文件)。在裝載的過(guò)程中,裝載器注意到它有一個(gè)基類(也就

是extends所要表示的意思),于是它再裝載基類。不管你創(chuàng)不創(chuàng)建基類對(duì)象,這個(gè)過(guò)程總會(huì)發(fā)

生。如果基類還有基類,那么第二個(gè)基類也會(huì)被裝載,依此類推。

(2)執(zhí)行根基類的static初始化,然后是下一個(gè)派生類的static初始化,依此類推。這個(gè)順序非常重

要,因?yàn)榕缮惖摹皊tatic初始化”有可能要依賴基類成員的正確初始化。

⑶當(dāng)所有必要的類都已經(jīng)裝載結(jié)束,開(kāi)始執(zhí)行main()方法體,并用newSubClass()創(chuàng)建對(duì)象。

⑷類SubClass存在父類,則調(diào)用父類的構(gòu)造函數(shù),你可以使用super來(lái)指定調(diào)用哪個(gè)構(gòu)造函數(shù)

(也就是Beetle()構(gòu)造函數(shù)所做的第一件事)。

基類的構(gòu)造過(guò)程以及構(gòu)造順序,同派生類的相同。首先基類中各個(gè)變量按照字面順序進(jìn)行初始

化,然后執(zhí)行基類的構(gòu)造函數(shù)的其余部分。

(5)對(duì)子類成員數(shù)據(jù)按照它們聲明的順序初始化,執(zhí)行子類構(gòu)造函數(shù)的其余部分。

Java初始化順序如圖:

1普通類初始化2續(xù)承外系初始化

5.2清理(垃圾回收機(jī)制)

L假設(shè)你的對(duì)象(并非使用new)獲得了一塊“特殊”的內(nèi)存區(qū)域,由于垃圾回收

器只知道釋放那些經(jīng)由new分配的內(nèi)存,所以它不知道該如何釋放該對(duì)象的這塊“特

殊”內(nèi)存。為了應(yīng)對(duì)這種情況,Java允許在類中定義一個(gè)名為finalize。的方法。

5.3構(gòu)造器的初始化順序

5.4垃圾回收機(jī)制

Java從堆分配空間的速度,可以和其他語(yǔ)言從堆棧上分配空間的速度相媲美。

1.引用計(jì)數(shù)是一種簡(jiǎn)單但速度很慢的垃圾回收技術(shù)。每個(gè)對(duì)象都含有一個(gè)引用計(jì)數(shù)

器,當(dāng)有引用連接至對(duì)象時(shí),引用計(jì)數(shù)加1.當(dāng)引用離開(kāi)作用域或被置為null時(shí),引

用計(jì)數(shù)減1.這種方法有一個(gè)缺陷,如果對(duì)象之間存在循環(huán)引用,可能會(huì)出現(xiàn)“對(duì)象

應(yīng)該被回收,但引用計(jì)數(shù)卻不為零”的情況。對(duì)于垃圾回收器而言,定位這樣的交

互自引用的對(duì)象組所需要的工作量極大。引用計(jì)數(shù)常用來(lái)說(shuō)明垃圾收集的工作方

式,但似乎從未被應(yīng)用于任何一種Java虛擬機(jī)實(shí)現(xiàn)中。

2.自適用的、分代的、停止-復(fù)制、標(biāo)記-清掃”式垃圾回收器

在一些更快的模式中,垃圾回收器并非基于弓I用計(jì)數(shù)技術(shù)。它們依據(jù)的思想是:對(duì)

于任何“活”的對(duì)象,一定能最終追溯到其存活在堆棧或靜態(tài)存儲(chǔ)區(qū)之中的引用。

這個(gè)引用鏈會(huì)穿過(guò)數(shù)個(gè)對(duì)象層。由此,如果從堆棧和靜態(tài)存儲(chǔ)區(qū)開(kāi)始,遍歷所有的

引用,就能找到所有”活“的對(duì)象。對(duì)于發(fā)現(xiàn)的每個(gè)引用,必須追蹤它所引用的對(duì)

象,然后是此對(duì)象包含的所有引用。如此反復(fù)進(jìn)行,直到”根源于堆棧和靜態(tài)存儲(chǔ)

區(qū)的引用“所形成的網(wǎng)絡(luò)全部被訪問(wèn)為止。

“停止-復(fù)制“:先暫停程序的運(yùn)行(所以它不屬于后臺(tái)回收模式),然后找到所

有存活的對(duì)象從當(dāng)前堆復(fù)制到另一個(gè)堆,沒(méi)有被復(fù)制的全部都是垃圾。當(dāng)對(duì)象被復(fù)

制到新堆時(shí),它們是一個(gè)個(gè)挨著的,所以新堆保持緊湊排列,然后就可以按簡(jiǎn)單、

直接地分配新空間了。當(dāng)把對(duì)象從一處搬到另一處時(shí),所有指向它的那些引用都必

須修正。

“標(biāo)記-清掃”:所依據(jù)的思路同樣是從堆棧和靜態(tài)存儲(chǔ)區(qū)出發(fā),遍歷所有的引

用,進(jìn)而找出所有存活的對(duì)象。每當(dāng)它找到一個(gè)存活對(duì)象,就會(huì)給對(duì)象一個(gè)標(biāo)記,

這個(gè)過(guò)程中不會(huì)回收任何對(duì)象。只有全部標(biāo)記工作完成的時(shí)候,清理動(dòng)作才會(huì)開(kāi)

始。在清理過(guò)程中,沒(méi)有標(biāo)記的對(duì)象將被釋放,不會(huì)發(fā)生任何復(fù)制動(dòng)作。

“自適用”:垃圾回收器將對(duì)上次回收動(dòng)作之后新分配的塊進(jìn)行整理。這對(duì)處理大

量短命的臨時(shí)對(duì)象很有幫助。垃圾回收器會(huì)定期進(jìn)行完整的清理動(dòng)作一大型對(duì)象任

然不會(huì)被復(fù)制(只是其代數(shù)會(huì)增加),內(nèi)含小型對(duì)象的那些塊則被復(fù)制并整理。

Java虛擬機(jī)會(huì)進(jìn)行監(jiān)視,如果所有對(duì)象都很穩(wěn)定,垃圾回收器的效率降低的話,就

切換到“標(biāo)記-清掃”方式;同樣,Java虛擬機(jī)會(huì)跟蹤“標(biāo)記-清掃”效果,要是堆

空間出現(xiàn)很對(duì)碎片,就會(huì)切換回“停止-復(fù)制”方式。這就是“自適應(yīng)”。

5.5枚舉類的初始化

5.6本章相關(guān)概念及問(wèn)題

1.this關(guān)鍵字:this關(guān)鍵字只能在方法內(nèi)部使用,表示對(duì)“調(diào)用方法的那個(gè)對(duì)象”

的引用。如果在方法內(nèi)部調(diào)用同一個(gè)類的另一個(gè)方法,就不必用this,直接調(diào)用即可。

第六章訪問(wèn)權(quán)限控制

6.1包名及import

-包在項(xiàng)目開(kāi)發(fā)時(shí)經(jīng)常用到,用于為了避免名稱重復(fù)而采用的一種措施。包的使用方式

是:

package包名;

如我在開(kāi)發(fā)時(shí)經(jīng)常使用到包名為packageedu.zut.cs.java;

建議包名為“域名倒置+項(xiàng)目名"。這里我用了學(xué)校的域名。

-若某個(gè)類需要訪問(wèn),則此類必須聲明為public.

若要訪問(wèn)不包package內(nèi)某個(gè)public類時(shí),我們要用到import。通過(guò)import引用其他

類;

格式:import包名.類名稱;

-JDK常用包的有以下幾個(gè):

(1)java.lang-包含Java語(yǔ)言的一些核心類,如String、Math、Integer、System和

Thread;

(2)java.awt-包含構(gòu)成抽象窗口工具集的多個(gè)類,用于構(gòu)建和管理應(yīng)用程序的圖形用

戶界面;

⑶java.applet-包含applet運(yùn)行所需要的一些類;

(4)-包含執(zhí)行與網(wǎng)絡(luò)相關(guān)的操作的類;

(5)java.io-包含執(zhí)行與網(wǎng)絡(luò)相關(guān)的一些類;

(6萬(wàn)ava.util-包含一些實(shí)用工具類,如定義系統(tǒng)特性、與日期日歷相關(guān)的方法.

6.2類成員的訪問(wèn)控制權(quán)限

-在中有種訪問(wèn)控制權(quán)限:、

Java4private,defaultprotectedspublic;

其中default控制權(quán)限為方法或變量的名字為其前沒(méi)有任何訪問(wèn)權(quán)限關(guān)鍵字限制。

-各個(gè)訪問(wèn)控制權(quán)限的范圍:

(1)private:如果成員方法或成員變量被private修飾,其只能被這個(gè)類的內(nèi)部使用;

(2)default:默認(rèn)的訪問(wèn)控制成員可以被這個(gè)包中的其他類訪問(wèn),子類不能訪問(wèn)在另

一個(gè)包內(nèi)的父類;

(3)protected:成員方法或變量被protected修飾,這個(gè)成員被同一個(gè)包中的其他類使

用,也可以被其他包的子類訪問(wèn);

(4)public:成員方法或變量被public修飾,其可以被所有包中的類訪問(wèn);

-附加一些Java的命名習(xí)慣:

(1)包中的字母均為小寫;

(2)類名、接口名應(yīng)當(dāng)使用名字,每個(gè)單詞首字母大寫;

(3)方法名、變量名第一個(gè)字母小寫,其余大寫;

(4)常量名的每個(gè)字母大寫。

1-從最大權(quán)限到最小權(quán)限依次為:public,protected,包訪問(wèn)權(quán)限(沒(méi)有關(guān)鍵詞)

和private。默認(rèn)訪問(wèn)權(quán)限沒(méi)有任何關(guān)鍵字,但通常是指包訪問(wèn)權(quán)限(有時(shí)也表

示成為friendly)。這就意味著當(dāng)前的包中的所有其他類對(duì)那個(gè)成員都有訪問(wèn)權(quán)

限,但對(duì)于這個(gè)包之外的所有類,這個(gè)成員卻是private。對(duì)private的使用是多

么的重要,在多線程環(huán)境中更是如此。

2.Java解釋器的運(yùn)行過(guò)程如下:首先,找出環(huán)境變量CLASSPATH(可以通過(guò)操作

系統(tǒng)來(lái)設(shè)置,有時(shí)也可通過(guò)安裝程序-用來(lái)在你的機(jī)器上安裝Java或者基于Java

的工具-來(lái)設(shè)置)。CLASSPATH包含一個(gè)或者多個(gè)目錄,用作查找.class文件的

根目錄。從根目錄開(kāi)始,解釋器獲取包的名稱并將每個(gè)句點(diǎn)替換成反斜杠,以

從CLASSPATH根中產(chǎn)生一個(gè)路徑名稱(于是,packagefoo.bar.baz就變成為

foo\bar\baz或foo/bar/baz或其他,這取決于操作系統(tǒng))。得到的路徑會(huì)與

CLASSPATH中的各個(gè)不同的項(xiàng)相連接,解釋器就在這些目錄中查找與你所要?jiǎng)?chuàng)

建的類名稱相關(guān)的.class文件。(解釋器還會(huì)去查找某些涉及Java解釋器所在

的位置的標(biāo)準(zhǔn)目錄。)

取得對(duì)某成員的訪問(wèn)權(quán)的唯一途徑是:使該成員成為通過(guò)不加

3.1)publico2)

訪問(wèn)權(quán)限修飾詞并將其它類放置于同一個(gè)包內(nèi)的方式給成員賦予包訪問(wèn)權(quán)。3)

繼承而來(lái)的類既可以訪問(wèn)public成員也可以訪問(wèn)protected成員(但不能訪問(wèn)

private成員卻不行)。只有在兩個(gè)類都處于同一個(gè)包內(nèi)時(shí),它才可以訪問(wèn)包訪

問(wèn)權(quán)限的成員。但現(xiàn)在不必?fù)?dān)心繼承和提供訪問(wèn)器

protectedo4)(accessor)

和變異器(mutator)方法(也稱get/set方法),以讀取和改變數(shù)值。

4.接口和實(shí)現(xiàn):訪問(wèn)權(quán)限的控制常被稱為是具體實(shí)現(xiàn)的隱藏。把數(shù)據(jù)和方法包裝

進(jìn)類中,以及具體實(shí)現(xiàn)的隱藏,常共同被稱為是封裝。其結(jié)果是一個(gè)同時(shí)帶有

特征和行為的數(shù)據(jù)類型。

5.類的訪問(wèn)權(quán)限:1)每個(gè)編譯單元(文件)都只能有一個(gè)public類。這表示,

每個(gè)編譯單元都有單一的公共接口,用public類來(lái)實(shí)現(xiàn)。public類的名稱必

須完全與含有該編譯單元的文件名相匹配,包括大小寫。3)雖然不是很常見(jiàn),

但編譯單元內(nèi)完全不帶public類也是可能的。在這種情況下,可以隨意對(duì)文件

命名。

第七章復(fù)用類

復(fù)用代碼有兩種方式:第一種方法非常直觀:只需在新的類中產(chǎn)生現(xiàn)有類的對(duì)象。由

于新的類是由現(xiàn)有類的對(duì)象所組成,這種方式稱為組合。第二種方式它按照現(xiàn)有類的

類型來(lái)創(chuàng)建新類。無(wú)需改變現(xiàn)有類的形式,采用現(xiàn)有類的形式并在其中添加新代碼。

這種神奇的方式稱為繼承。第三種方式是代理:這是繼承和組合之間的中庸之道。

7.1組合語(yǔ)法

只需將對(duì)象引用置于新類中即可。對(duì)于非基本類型的對(duì)象,必須將其引用置于新的類

中。但可以直接定義基本類型對(duì)象。類中的域?yàn)榛绢愋蜁r(shí)能夠自動(dòng)被初始化為零。

但是對(duì)引用會(huì)被初始化為null。如果想初始化這些引用,可以在代碼中的下列位置進(jìn)

行:

1.在定義對(duì)象的地方。這意味著它們總是能夠在構(gòu)造器被調(diào)用之前被初始化。

2.在類的構(gòu)造器中。

3.就在正要使用這些對(duì)象之前,這種方式稱為惰性初始化。在生成對(duì)象不值得及

不必每次都生成對(duì)象的情況下,這種方式可以減少額外的負(fù)擔(dān)。

7.2繼承語(yǔ)法

在繼承過(guò)程中,需要先聲明“新類與舊類相似”。這種聲明是通過(guò)在類主體的左邊花

括號(hào)之前,書寫后面緊隨基類名稱的關(guān)鍵字extends而實(shí)現(xiàn)的。為了繼承,一般的規(guī)

則是將所有的數(shù)據(jù)成員都指定為private,將所有的方法指定為public。

1.初始化基類:繼承并不只是復(fù)制基類的接口。當(dāng)創(chuàng)建了一個(gè)導(dǎo)出類的對(duì)象時(shí),

該對(duì)象包含了一個(gè)基類的子對(duì)象。這個(gè)子對(duì)象與你用基類直接創(chuàng)建的對(duì)象是一

樣的。二者的區(qū)別在于,后者來(lái)自于外部,而基類的子對(duì)象被包含在導(dǎo)出類對(duì)

象內(nèi)部。對(duì)基類子對(duì)象的正確初始化也是至關(guān)重要的,而且也僅有一種方法來(lái)

保證這一點(diǎn):在構(gòu)造器中調(diào)用基類構(gòu)造器來(lái)執(zhí)行初始化。Java會(huì)自動(dòng)在導(dǎo)出類

中的構(gòu)造器中插入對(duì)基類構(gòu)造器的調(diào)用。

2.JavaSE5新增加了@Override注解,當(dāng)你想要復(fù)寫某個(gè)方法時(shí),可以選擇添加這

個(gè)注解。

3.向上轉(zhuǎn)型:新類和基類之間的關(guān)系,這種關(guān)系可以用“新類是現(xiàn)有類的一種類

型”。

4.是否使用繼承:一個(gè)最清晰的判斷辦法是問(wèn)一問(wèn)自己是否需要從新類向基類進(jìn)

行向上轉(zhuǎn)型。如果必須向上轉(zhuǎn)型,則繼承是必要的。

7.3final關(guān)鍵字

final通常指:“這是無(wú)法改變的"。可能用到final的三種情況:數(shù)據(jù)、方法和類。

1.final數(shù)據(jù)

數(shù)據(jù)恒定不變:1)一個(gè)永不改變的編譯時(shí)常量。2)一個(gè)在運(yùn)行時(shí)被初始化的值,而

你不希望它被改變。它可以在編譯時(shí)執(zhí)行計(jì)算。但這類常量必須是基于基本數(shù)據(jù)類

型,并且以關(guān)鍵字final表示。一個(gè)既是static又是final的域只占據(jù)一段不能改變的存

儲(chǔ)空間。對(duì)于基本類型,final使數(shù)值恒定不變;而對(duì)于對(duì)象引用,final使引用恒定

不變。而對(duì)象其自身卻是可以被修改的,Java并未提供使任何對(duì)象恒定不變的途徑。

定義為public,則可以被用于包之外;定位為static,則強(qiáng)調(diào)只有一份;定義為

final,則說(shuō)明它是一個(gè)常量。并不是某個(gè)數(shù)據(jù)是final就認(rèn)為在編譯時(shí)可以知道它的

值。空白final:所謂空白final是指被聲明為final但又未給定初值的域。必須在

域的定義處或者每個(gè)構(gòu)造器中用表達(dá)式對(duì)final進(jìn)行賦值,這正是final域在使用前

總是被初始化的原因所在。final參數(shù):Java允許在參數(shù)列表中以聲明的方式將參數(shù)

指明為finalo這意味著你無(wú)法在方法中更改參數(shù)引用所指向的對(duì)象。

2.final方法

使用final方法可以防繼承修改,又可以提高效率(但在JavaSE5/6中,應(yīng)該讓編譯器

去處理效率)。類中的所有private方法都隱藏地指定為final的。

3.final類

由于final類禁止繼承,所有final類中所有的方法都隱式指定為是final的,因?yàn)闊o(wú)法

覆蓋它們。

4.thedifferentofstaticbetweenfinal?

4.1static關(guān)鍵字

static關(guān)鍵字可以用來(lái)修飾類的變量,方法和內(nèi)部類。static是靜態(tài)的意思,也是全局的意

思它定義的東西,屬于全局與類相關(guān),不與具體實(shí)例相關(guān)。就是說(shuō)它調(diào)用的時(shí)候,只是

ClassName.method。,而不是newClassName().method()0newClassName()不就是一個(gè)對(duì)象了

嗎?static的變量和方法不可以這樣調(diào)用的。它不與具體的實(shí)例有關(guān)。

4.2final關(guān)鍵字

final關(guān)鍵字有三個(gè)東西可以修飾的。修飾類,方法,變量。詳細(xì)解釋一下:

在類的聲明中使用final

使用了foial的類不能再派生子類,就是說(shuō)不可以被繼承了。有些java的面試題里

面,問(wèn)String可不可以被繼承。答案是不可以,因?yàn)閖ava.lang.String是一^final

類。這可以保證String對(duì)象方法的調(diào)用確實(shí)運(yùn)行的是String類的方法,而不是經(jīng)其

子類重寫后的方法。

在方法聲明中使用final

被定義為final的方法不能被重寫了,如果定義類為final的話,是所有的方法都不

能重寫。而我們只需要類中的某幾個(gè)方法,不可以被重寫,就在方法前加final

了。而且定義為final的方法執(zhí)行效率要高的啊。

在變量聲明中使用final

這樣的變量就是常量了,在程序中這樣的變量不可以被修改的。修改的話編譯器會(huì)

抱錯(cuò)的。而且執(zhí)行效率也是比普通的變量要高。final的變量如果沒(méi)有賦予初值的

話,其他方法就必需給他賦值,但只能賦值一次。

注意:子類不能重寫父類的靜態(tài)方法哦,也不能把父類不是靜態(tài)的重寫成靜態(tài)的方法。想隱藏

父類的靜態(tài)方法的話,在子類中聲明和父類相同的方法就行了。

5.final、finally和finalize的區(qū)另[|?

final用于聲明屬性,方法和類,分別表示屬性不

可變,方法不可覆蓋,類不可繼承。

finally是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行。

finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方

法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等

final—修飾符(關(guān)鍵字)如果一個(gè)類被聲明為final,意味著它不能再派生出新的子類,不

能作為父類被繼承。因此一個(gè)類不能既被聲明為abstract的,又被聲明為final的。將變量或方法

聲明為final,可以保證它們?cè)谑褂弥胁槐桓淖?。被聲明為final的變量必須在聲明時(shí)給定初值,而

在以后的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載。

finally—在異常處理時(shí)提供行nally塊來(lái)執(zhí)行任何清除操作。如果拋出一個(gè)異常,那么相匹

配的catch子句就會(huì)執(zhí)行,然后控制就會(huì)進(jìn)入finally塊(如果有的話)。

finalize一方法名。Java技術(shù)允許使用finalizeQ方法在垃圾收集器將對(duì)象從內(nèi)存中清除出

去之前做必要的清理工作。這個(gè)方法是由垃圾收集器在確定這個(gè)對(duì)象沒(méi)有被引用時(shí)對(duì)這個(gè)對(duì)象調(diào)

用的。它是在Object類中定義的,因此所有的類都繼承了它。子類覆蓋finalize。方法以整理系統(tǒng)

資源或者執(zhí)行其他清理工作。finalizeQ方法是在垃圾收集器刪除對(duì)象之前對(duì)這個(gè)對(duì)象調(diào)用的。

7.4初始化及類的加載

初次使用之處也是static初始化發(fā)生之處。所有的static對(duì)象和static代碼段都會(huì)

在加載時(shí)依程序中的順序(即:定義類時(shí)的書寫順序)而依次初始化。當(dāng)然,定義為

static的東西只會(huì)被初始化一次。

第八章多態(tài)

多態(tài)通過(guò)分離做什么和怎么做,從另一角度將接口和實(shí)現(xiàn)分離開(kāi)來(lái)。

8.1多態(tài)

1.多態(tài)的作用:如果有這樣的一個(gè)簡(jiǎn)單方法,它僅接收基類作為參數(shù),而不是那些特

殊的導(dǎo)出類。我們不管導(dǎo)出類的存在,編寫的代碼只是與基類打交道。當(dāng)然,在方法

里編譯器是無(wú)法識(shí)別導(dǎo)出類還是基類的。

2.將一個(gè)方法調(diào)用同一個(gè)方法主體關(guān)聯(lián)起來(lái)被稱為綁定。若在程序執(zhí)行之前進(jìn)行綁

定,叫做前期綁定。后期綁定:就是在運(yùn)行時(shí)根據(jù)對(duì)象的類型進(jìn)行綁定。如果一種語(yǔ)

言能實(shí)現(xiàn)后期綁定,就必須具有某種機(jī)制,以便在運(yùn)行時(shí)能判斷對(duì)象的類型,從而調(diào)

用恰當(dāng)?shù)姆椒?。也就是說(shuō),編譯器一直不知道對(duì)象的類型,但是方法調(diào)用機(jī)制能找到

正確的方法體,并加以調(diào)用。其實(shí)是在對(duì)象中安置某種“類型信息”。Java中除了

static方法和final方法(private方法屬于final方法)之外,其他所有的方法都是后期

綁定。

3.域和靜態(tài)方法:任何域訪問(wèn)都由編譯器解析,因此不是多態(tài)的。只有非靜態(tài)方法是

多態(tài)的,域是由編譯器決定的。靜態(tài)方法是與類,而并非與單個(gè)對(duì)象相關(guān)聯(lián)。所以非

靜態(tài)方法是不具有多態(tài)性的。

8.2構(gòu)造器和多態(tài)

1.構(gòu)造器實(shí)際上是static方法,只不過(guò)該static聲明是隱式的,因此并不具有多態(tài)性。

構(gòu)造器有一項(xiàng)特殊的任務(wù):檢查對(duì)象是否被正確地構(gòu)造。導(dǎo)出類只能訪問(wèn)它自己的成

員,不能訪問(wèn)基類中的成員。對(duì)象調(diào)用構(gòu)造器要遵照下面的順序:

1)調(diào)用基類構(gòu)造器。這個(gè)步驟會(huì)不斷地反復(fù)遞歸下去。2)按聲明順序調(diào)用成員的初

始化方法。3)調(diào)用導(dǎo)出構(gòu)造器的主體。

2.構(gòu)造器內(nèi)部的多態(tài)方法的行為

在一般的方法內(nèi)部,動(dòng)態(tài)綁定的調(diào)用是運(yùn)行時(shí)才決定的,因?yàn)閷?duì)象無(wú)法知道它是屬于

方法所在的那個(gè)類,還是屬于那個(gè)類的導(dǎo)出類。

3.構(gòu)造器初始化的過(guò)程:1)在其他任何事物發(fā)生之前,將分配給對(duì)象的存儲(chǔ)空間初始

化為二進(jìn)制的零。2)調(diào)用基類構(gòu)造器。3)按照聲明的順序調(diào)用成員的初始化方法。

4)調(diào)用導(dǎo)出類的構(gòu)造體。

4.協(xié)變返回類型:JavaSE5中添加了協(xié)變返回類型,它表示在導(dǎo)出類中的被覆蓋方法可

以返回基類方法的返回類型的某種導(dǎo)出類型。

第九章接口

9」抽象類和抽象方法

抽象類是普通類與接口之間的一種中庸之道。包含抽象方法的類叫做抽象類。如果一

個(gè)類包含一個(gè)或多個(gè)抽象方法,該類必須被限定為抽象的。(否則,編譯器就會(huì)報(bào)

錯(cuò))。為抽象類創(chuàng)建對(duì)象是不安全的(為什么不安全,因?yàn)楫?dāng)你想調(diào)用該抽象方法

時(shí),卻沒(méi)有方法體),所以我們會(huì)從編譯器那里得到一條出錯(cuò)消息。這樣編譯器會(huì)確

保抽象類的純粹性。

92接口

1.接口被用來(lái)建立類與類之間的協(xié)議。如果接口不添加public關(guān)鍵字,則它只具有包

訪問(wèn)權(quán)限,這樣它就只能在同一個(gè)包內(nèi)可用。接口也可以包含域,但是這些域隱式地

是static和final的。只要一個(gè)方法操作的是類而非接口,那么你就只能使用這個(gè)類及

其子類。創(chuàng)建一個(gè)能夠根據(jù)所傳遞的參數(shù)對(duì)象的不同而具有不同行為的方法,被稱為

策略模式。策略設(shè)計(jì)模式:你可以用任何你想要的對(duì)象來(lái)調(diào)用為的方法,只要你的對(duì)

象遵循我的接口。類庫(kù)是被發(fā)現(xiàn)而非創(chuàng)建的,在這種情況下,可以使用適配器設(shè)計(jì)模

式。適配器中的代碼獎(jiǎng)接受你所擁有的接口,并產(chǎn)生你所需要的接口。

2捱口可以多重繼承,也可以嵌套在類或其他接口中。

34妾口中的域:因?yàn)槟惴湃虢涌谥械娜魏斡蚨甲詣?dòng)是static和final的。所以接口就稱

為了一種很便捷的用來(lái)創(chuàng)建常量組的工具,但有了JavaSE5,你可以用enum代替。在

接口中定義的域不能是“空f(shuō)inal”,但是可以被非常量表達(dá)式初始化。

4.當(dāng)實(shí)現(xiàn)某個(gè)接口時(shí),并不需要實(shí)現(xiàn)嵌套在其內(nèi)部的任何接口。而且,private接口不

能定義它的類之外被實(shí)現(xiàn)。

5推口是實(shí)現(xiàn)多重繼承的途徑,而生成遵循某個(gè)接口的對(duì)象的典型方式就是工廠方法

設(shè)計(jì)模式。

9.3多重繼承

將所有的接口名都置于implements關(guān)鍵字之后,用逗號(hào)將它們一一隔開(kāi)??梢岳^承任

意多個(gè)接口,并可以向上轉(zhuǎn)型為每個(gè)接口。因?yàn)槊恳粋€(gè)接口都是一個(gè)獨(dú)立類型。

第十章內(nèi)部類

工工.工嵌套類和內(nèi)部類

可以在一個(gè)類的內(nèi)部定義另一個(gè)類,這種類稱為嵌套類(nestedclasses),它有兩種

類型:靜態(tài)嵌套類和非靜態(tài)嵌套類。靜態(tài)嵌套類使用很少,最重要的是非靜態(tài)嵌套

類,也即是被稱作為內(nèi)部類嵌套類從開(kāi)始引入。其中類又可

(inner)oJDK1.1inner

分為三種:

其一、在一個(gè)類(外部類)中直接定義的內(nèi)部類;

其二、在一個(gè)方法(外部類的方法)中定義的內(nèi)部類;

其三、匿名內(nèi)部類。

靜態(tài)嵌套類

publicclassStaticTest{

privatestaticStringname="javaJohn”;

privateStringid="X001";

staticclassPerson{

privateStringaddress="swjtu,chenDu,China";

publicStringmail="josserchai@”;〃內(nèi)部類公有成員

publicvoiddisplayO{

〃System.out.println(id);〃不能直接訪問(wèn)夕卜部類的非靜態(tài)成員

System.o〃,printlnGw%e);〃只能直接訪問(wèn)夕卜部類的靜態(tài)成員

System.owZ.println("Inner"+address);//訪問(wèn)本內(nèi)部類成員。

publicvoidprintlnfo(){

Personperson=newPerson();

person.display();

“System.out.println(mail);〃不可訪問(wèn)

〃System.out.println(address);〃不可訪問(wèn)

System。"力println(person.address);//可以訪問(wèn)內(nèi)部類的私有成員

System.o“f.println(person.mail);//可以訪問(wèn)內(nèi)部類的公有成員

在靜態(tài)嵌套類內(nèi)部,不能訪問(wèn)外部類的非靜態(tài)成員,這是由Java語(yǔ)法中"靜態(tài)方

法不能直接訪問(wèn)非靜態(tài)成員”所限定。若想訪問(wèn)外部類的變量,必須通過(guò)其它方法解

決,由于這個(gè)原因,靜態(tài)嵌套類使用很少。注意,外部類訪問(wèn)內(nèi)部類的的成員有些特

別,不能直接訪問(wèn),但可以通過(guò)內(nèi)部類來(lái)訪問(wèn),這是因?yàn)殪o態(tài)嵌套內(nèi)的所有成員和方

法默認(rèn)為靜態(tài)的了。同時(shí)注意,內(nèi)部靜態(tài)類Person只在類StaticTest范圍內(nèi)可見(jiàn),若

在其它類中引用或初始化,均是錯(cuò)誤的。

11.1.2在外部類中定義內(nèi)部類(非靜態(tài)嵌套類)

對(duì)于內(nèi)部類,通常在定義類的class關(guān)鍵字前不加public或private等限制符,若

加了沒(méi)有任何影響,同時(shí)好像這些限定符對(duì)內(nèi)部類的變量和方法也沒(méi)有影響(?)。

11.1.3內(nèi)部類和匿名內(nèi)部類

內(nèi)部類有如下特征:

1.內(nèi)部類被編譯成名為OuterClassName$lnnerClassName.class的類。

2.內(nèi)部類可以引用定義在它嵌套的外部類中的數(shù)據(jù)和方法,所以不需要將外部類

對(duì)象的引用傳遞給內(nèi)部類的構(gòu)造方法,因此,內(nèi)部類可以拿程序簡(jiǎn)單和簡(jiǎn)潔。

3.聲明用可見(jiàn)性修飾符聲明內(nèi)部類,遵從應(yīng)用于一般類成員的可見(jiàn)性規(guī)則。

4.可以將內(nèi)部類聲明為static。一個(gè)static內(nèi)部類可以使用外部類的名字訪問(wèn)。一

個(gè)static類是不能訪問(wèn)外部類的非靜態(tài)成員的。

5.內(nèi)部類的對(duì)象經(jīng)常在外部類中創(chuàng)建。但是也可以從另一個(gè)類中創(chuàng)建一個(gè)內(nèi)部類

的對(duì)象。如果該內(nèi)部是非靜態(tài)的,就必須先創(chuàng)建一個(gè)外部類的實(shí)例,然后用下

面的語(yǔ)法創(chuàng)建一個(gè)內(nèi)部類的對(duì)象:

1.OuterClass.InnerClassinnerObject=OutObject.newlnnerclass()

.如果內(nèi)部類是靜態(tài)的,那么使用下面的語(yǔ)法為它創(chuàng)建一個(gè)對(duì)象:

Java代碼

2.OuterClass.InnerClassinnerObject=newOutObject.lnnerclass()

匿名內(nèi)部類是一種特殊的內(nèi)部類,所以有很多方面都應(yīng)把它當(dāng)作內(nèi)部類對(duì)待。除此之

外,它還有以下特征。

1.匿名內(nèi)部類必須是擴(kuò)展父類或?qū)崿F(xiàn)接口的。但是它不能有明確的extends或

implements語(yǔ)句。

2.匿名內(nèi)部類必須實(shí)現(xiàn)父類或接口中所有的抽象方法。

3.匿名內(nèi)部類總是使用父類的無(wú)參數(shù)構(gòu)造方法來(lái)創(chuàng)建實(shí)例。如果匿名內(nèi)部類實(shí)現(xiàn)

了接口,構(gòu)造方法就是Object。.

4.匿名內(nèi)部類編譯為名為OuterClassName$n.class的類。如,如果外部類Test有

兩個(gè)匿名類,那么它們就編譯成和

Test$l.classTest$2.classo

第十一章持有對(duì)象

Java實(shí)現(xiàn)類庫(kù)還提供了一套相當(dāng)完整的容器類來(lái)解決這個(gè)問(wèn)題,其中基本的類型是

List、Set、Queue和Map,這些對(duì)象也稱為集合類。Set對(duì)于每個(gè)值都只保存一個(gè)對(duì)

象,Map是允許你將某些對(duì)象與其他一些對(duì)象關(guān)聯(lián)起來(lái)的關(guān)聯(lián)數(shù)組,Java容器類都可

以自動(dòng)調(diào)整自己的尺寸。

11.1基本概念

l.Java容器類類庫(kù)的用途是“保存對(duì)象”。并劃分為兩個(gè)不同的概念。

一個(gè)獨(dú)立元素的序列,這些元素都服從一條或者多條規(guī)則。

1)Collectiono

List必須按照插入的順序保存元素,而Set不能有重復(fù)元素。Queue按照排隊(duì)規(guī)

則來(lái)確定對(duì)象產(chǎn)生的順序(通常與它們插入的順序相同)。

2)Map。一組成對(duì)的“鍵值對(duì)”對(duì)象,允許你用鍵來(lái)查找值。ArrayList允

許你使用數(shù)字來(lái)查找。也被稱為“關(guān)聯(lián)數(shù)組”或者“字典”。

2.Arrays.asList()方法接受一個(gè)數(shù)組或是一個(gè)用逗號(hào)分隔維元素列表(使用可變參數(shù)),

并將其轉(zhuǎn)換為一個(gè)List對(duì)象。Collections.addAII。方法接受一個(gè)Collection對(duì)象,以及一

個(gè)數(shù)組或是一個(gè)用逗號(hào)分割的列表,將元素添加到Collection中。

3.一共有三種風(fēng)格的Map:HashMap、TreeMap和LinkedHashMap。與HashSet一樣,

HashMap也提供了最快的查找技術(shù),也沒(méi)有按照任何明顯的順序來(lái)保存其元素。

TreeMap按照比較結(jié)果的升序保存鍵,而linkedHashMap則按照插入順序保存鍵,同

時(shí)保留了HashMap的查詢速度。

11.2List及LinkedList

可使元素維持在特定的序列中,有兩種基本類型的

ListListo

1)基本的ArrayList,它長(zhǎng)于隨機(jī)訪問(wèn)元素,但是在List的中間插入和移除元素時(shí)

較慢。

2)LinkedList,它通過(guò)代價(jià)較低的在List中間進(jìn)行的插入和刪除操作,提供了優(yōu)化

的順序訪問(wèn)。LinkedList在隨機(jī)訪問(wèn)相對(duì)較慢,但是它的特性集較ArrayList更大。

11.3迭代器

迭代器是一個(gè)對(duì)象,它的工作是遍歷并選擇序列中的對(duì)象,而客戶端程序員不必之道

或關(guān)心該序列底層的結(jié)構(gòu)。Java的Iterator只能單向移動(dòng)。這個(gè)Iterator只能用來(lái):

1)使用方法iterator。要求容器返回一個(gè)Iterator。Iterator將準(zhǔn)備好返回序列的第

一個(gè)元素。

2)使用next。獲得序列中的下一個(gè)元素。

3)使用hasNext。檢查序列中是否還有元素。

4)使用remove。將迭代器新近返回的元素刪除。

1.Listiterator

Listiterator是一個(gè)更加強(qiáng)大的Iterator的子類型,它只能用于各種List類的訪問(wèn)。盡管

Iterator只能向前移動(dòng),但是Listiterator可以雙向移動(dòng)。

2.Stack

“棧”通常是指'‘后進(jìn)先出"的容器。LinkedList具有能夠直接實(shí)現(xiàn)棧的所有功能的方

法,因此可以直接將LinkedList作為棧使用。

3.Set

Set最常用被使用的是測(cè)試歸屬性,你可以很容易地詢問(wèn)某個(gè)對(duì)象是否在某個(gè)Set中。

TreeSet將元素存儲(chǔ)在紅-黑樹數(shù)據(jù)結(jié)構(gòu)中,而HashSet使用的是散列函數(shù)。

LinkedHashList因?yàn)椴樵兯俣鹊脑蛞彩褂昧松⒘小?/p>

4.Map是將對(duì)象映射到其他對(duì)象的能力。

5.Queue

隊(duì)列是一個(gè)典型的先進(jìn)先出的容器。隊(duì)列在并發(fā)編程中特別重要。LinkedList提供了方

法以支持隊(duì)列的行為,并且它將實(shí)現(xiàn)Queue接口,因此LinkedList可用作Queue的一

種實(shí)現(xiàn)。PriotityQueue提供了典型的隊(duì)列規(guī)則。

6.Foreach與迭代器:到目前為止,foreach語(yǔ)法主要用于數(shù)組,但是它也可以應(yīng)用于

任何Collection對(duì)象。JavaSE5引入了新的被稱為Iteratable的接口,該接口包含一個(gè)能

夠產(chǎn)生Iterator的iterator。方法,并且Itearable接口被foreach用來(lái)在序列中移動(dòng)。在

JavaSE5中,大量的類都是Iterable類型,主要包含所有的Collection類(但是不包括

各種Map)。當(dāng)你有一個(gè)接口并需要另一個(gè)接口時(shí),編寫適配器就可以解決問(wèn)題。

7.總結(jié):

1)數(shù)組將數(shù)字與對(duì)象聯(lián)系起來(lái)。

2)Collection保存單一的元素,而Map保存相關(guān)聯(lián)的鍵值對(duì)。容器不能持有基本類

型,但是自動(dòng)包裝機(jī)制會(huì)仔細(xì)地執(zhí)行基本類型到容器中所持有的包裝類型之間的雙向

轉(zhuǎn)換。

3)像數(shù)組一樣,List也建立數(shù)字索引與對(duì)象的關(guān)聯(lián),因此,數(shù)組和List都是排序好的

容器。List能夠自動(dòng)擴(kuò)容。

4)如果要進(jìn)行大量的隨機(jī)訪問(wèn),就使用ArrayList。如果要經(jīng)常從表中間插入或刪除元

素,則應(yīng)該使用

LinkedListo

5)各種Queue以及棧的行為,由LinkedList提供支持。

6)Map是一種將對(duì)象(而非數(shù)字)與對(duì)象相關(guān)聯(lián)的設(shè)計(jì)。HashMap設(shè)計(jì)用來(lái)快速訪

問(wèn);而TreeMap保持“鍵"始終處于排序狀態(tài),所以沒(méi)有HashMap快。

LinkedHashMap保持元素插入的順序,但是也通過(guò)散列提供了快速訪問(wèn)能力。

7)Set不接受重復(fù)元素。HashSet提供最快的查詢速度,而TreeSet保持元素處于排序

狀態(tài)。LinkedHashSet以插入順序保存元素。

新程序中不應(yīng)該使用過(guò)時(shí)的、和

8)VectorHashtableStacko

:Iterator夕-------C-o-llection------

-j.jProducesProduces

ListlteratorH----------4ListijSet!iQueue

jprndiirpc1i!”HashMapTreeMap

>..K■I^9J————————?_~——————

■■■■■?■■■■■???????■■■■■^|???????a?.???????■??.?

??

胃「1

LinkedHashMap

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論