版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度城市景觀改造項(xiàng)目拆除工程合同3篇
- 2025年度乘風(fēng)破浪或有事的動(dòng)態(tài)智能家居系統(tǒng)銷售合同3篇
- 2025年度車庫(kù)停車收費(fèi)系統(tǒng)升級(jí)合同8篇
- 2025年度個(gè)人勞務(wù)合同(環(huán)境工程師專用)4篇
- 2025年度豪華郵輪運(yùn)輸合同規(guī)范范本3篇
- 2025年度藝術(shù)品代理銷售合同(年度版)4篇
- 二零二五年度醫(yī)療設(shè)備遠(yuǎn)期銷售合同4篇
- 二零二五年新推出房產(chǎn)贈(zèng)與公證合同3篇
- 2025年度住宅窗簾定制與智能家居聯(lián)動(dòng)合同范本4篇
- 二零二五年按摩技師個(gè)人品牌授權(quán)合作合同模板2篇
- 鋼筋桁架樓承板施工方案
- DL-T5434-2021電力建設(shè)工程監(jiān)理規(guī)范
- 2024年上海核工程研究設(shè)計(jì)院股份有限公司招聘筆試沖刺題(帶答案解析)
- 眼的解剖結(jié)構(gòu)與生理功能課件
- 2024年銀行考試-興業(yè)銀行筆試參考題庫(kù)含答案
- 泵站運(yùn)行管理現(xiàn)狀改善措施
- 2024屆武漢市部分學(xué)校中考一模數(shù)學(xué)試題含解析
- SYT 0447-2014《 埋地鋼制管道環(huán)氧煤瀝青防腐層技術(shù)標(biāo)準(zhǔn)》
- 浙教版七年級(jí)下冊(cè)科學(xué)全冊(cè)課件
- 弧度制及弧度制與角度制的換算
- 瓦楞紙箱計(jì)算公式測(cè)量方法
評(píng)論
0/150
提交評(píng)論