Methodoverloading
|_Distinguishingoverloadedmethods
Ifthemethodshavathesamename,howcanjavaknowwhichmethodyoumean?There'sasimplerule:Eachoverloadedmethodmusttakeauniquelistofargumenttypes.
|_OverloadingwithPRimitives
Wecanknowthattheconstantvalue5istreatedasint,soifanoverloadedmethodisavailablethattakesasint,itisused.Inallothercases,ifyouhavaadatatypethatissmallerthantheargumentinthemethod,thatdatatypeispromoted.charproducesasightlydifferenteffect,sinceifitdoesn'tfindanexactcharmatch,itispromotedtoint.
Supposethemethodstakenarrowerprimitivevalues.Ifyourargumentiswider,thenyoumustperformanarrowingconversionwithacast.Ifyoudon'tdothis,thecompilerwillissueanerrormessage.
|_Overloadingonreturnvalues
void f() {}int f() {return 1;}
Ifwejustwanttocallamethodforitssideeffect,suchas:
f();
howcanJavadeterminewhichf()shouldbecalled?Andhowcouldsomeonereadingthecodeseeit?BecauSEOfthissortofproblem,youcannotusereturnvaluetypestodistinguishoverloadedmethods.
DefaultconstructorsIfyoucreateaclassthathasnoconstructors,thecompilerwillautomaticallycreateadefaultconstructorforyou.
Ifyoudefineanyconstructors(withorwithoutarguments),thecompilerwillnotsynthesizeoneforyou.
Whenyoudon'tputinanyconstructors,it'sasifthecompilersays,"Youareboundtoneedsomeconstructorsoletmemakeoneforyou."Butifyouwriteaconstructor,thecompilersays,"You'rewrittenaconstructorsoyouknowwhatyou'redoing;ifyoudidn'tputinadefaultit'sbecauseyoumeanttoleaveitout."
ThethiskeyWord
|_callingconstructorsfromconstructors
Whileyoucancalloneconstructorusingthis,youcannotcalltwo.Inaddition,theconstructorcallmustbethefirstthingyoudo,oryou'llgetacompilererrormessage.
|_themeaningofstatic
Itmeansthatthereisnothisforthatparticularmethod.Youcannotcallnon-staticmethodsfrominsidestaticmethod(althoughthereverseispossible),andyoucancallastaticmethodfortheclassitself,withoutanyobject.Infact,that'sprimarilywhatastaticmethodiffor.
Cleanup:finalizationandgarbagecollection
Whenthegarbagecollectorisreadytoreleasethestorageusedforyourobject,itwillfirstcallfinalize(),andonlyonthenextgarbage-collectionpasswillitreclaimtheobject'smemory.
InJava,objectsdonotalwaysgetgarbagecollected.Or,putanotherway:
1、Yourobjectsmightnotgetgarbagecollected.
2、Garbagecollectionisnotdestruction.
3、Garbagecollectionisonlyaboutmemory.
Youmightfindthatthestorageforanobjectnevergetsreleasedbecauseyourprogramnevernearsthepointofrunningoutofstorage.Ifyourprogramcompletesandthegarbagecollectornevergetsaroundtoreleasingthestorageforanyofyourobjects,thatstoragewillbereturnedtotheOperatingsystemenmasseastheprogramexits.Thisisagoodthing,becausegarbagecollectionhassomeoverhead,andifyouneverdoit,youneverincurthatexpense.
|_Whatisfinalize()for?
Itwouldseemthatfinalize()isinplacebecauseofthepossibilitythatyou'lldosomethingClikebyallocatingmemoryusingamechanismotherthanthenormaloneinJava.Thiscanhappenprimarilythoughnativemethods,whichareawaytocallnon-JavacodefromJava.CandC++aretheonlylanguagescurrentlysupportedbynativemethods,butsincetheycancallsubprogramsinotherlanguages,youcaneffectivelycallanything.Insidethenon-Javacode,C'smalloc()familyoffunctionmightbecalledtoallocatestorage,andunlessyoucallfree(),thatstoragewillnotbereleased,causingamemoryleak.Ofcourse,free()isaCandC++function,soyou'dneedtocallitinanativemethodinsideyourfinalize().
Afterreadingthis,youprobablygettheideathatyouwon'tusefinalize()much(JoshuaBlochgoesfurther:"finalizesareunpredictable,oftendangerous,andgenerallyunnecessary.").Youarecorrect;itisnottheappropriateplacefornormalcleanuptooccur.Sowhereshouldnormalcleanupbeperformed?
|_Youmustperformcleanup
Ifyouwantsomekindofcleanupperformedotherthanstoragerelease,youmuststillexplicitlycallanappropriatemethodinJava,whichistheequivalentofaC++destructorwithouttheconvenience.
Rememberthatneithergarbagecollectionnorfinalizationisguaranteed.IftheJVMisn'tclosetorunningoutofmemory,thenitmightnotwastetimerecoveringmemorythroughgarbagecollection.
|_Howagarbagecollectorworks
首先,JVM有多種實現形式,不同類型的JVM實現上會有所差別,速度、穩定性也不一樣,因此應該辯證的看待下面的文字-:)
在一些JVM中,Java的堆與C++中的堆很是不同。C++中的堆就像一個大院子,每個對象占據一塊地方。而Java中的堆則更像是一個傳送帶,因而加快了為對象分配內存的速度,就如同C++中的棧幀移動一般,隨著"heappointer"的移動其分配內存的速度稍遜與棧(forJavaheap,there'salittleextraoverhead forbookkeeping,butit'snothinglikesearchingforstorage)。
一個簡單且緩慢的垃圾回收方案是采用referencecounting。每個對象包含一個引用計數器,GC遍歷整個對象列表,當它發現一個引用計數器為零時,釋放該對象的內存。管理計數器引用在程序的整個生命周期中有小的常量的開銷。缺點是彼此循環引用的對象雖為垃圾但是因其引用計數器非零,因此得不到釋放。該方案通常被用來解釋一種可能的垃圾回收機制,但是似乎從沒有被任何JVM的具體實現采用過。
一個更快的方案是基于一種思想:non-dead對象必須最終能夠被生存在棧上或是靜態存儲區上的引用所追蹤到。這個鏈條可能穿越基層對象,從棧上和靜態存儲區上的所有引用開始,跟蹤進引用指向的對象,然后跟蹤對象里的所有引用,如此反復,可以找到所有生存的對象。值得注意的是,彼此循環引用對象的釋放不在是問題了,它們不能被找到,自動成為了垃圾。
JVM采用適合的垃圾回收方案,可以根據不同的情況進行切換。兩種主要的機制是"stop-and-copy"、"mark-and-sweep"。stop-and-copy方案暫停當前的程序,留下所有垃圾,只將生存的對象從一個堆拷貝到另一個堆中。mark-and-sweep方案一直被早期的Sun'sJVM采用,一般而言,它速度很慢,但是當垃圾很少甚至是沒有垃圾產生的時候,其速度是很快的。mark-and-copy方案同樣遵循從棧上或是靜態存儲區上的引用追蹤對象的邏輯,每次它發現一個對象,對象就被設置一個標記,當mark程序執行完成后,sweep才能得到執行。sweep執行期間,死亡對象被釋放。由于沒有copy發生,如果收集器決定壓緊碎片堆,只能通過移動對象的方式。
JVM監視GC的效率。如果所有對象長期生存,它切換到mark-and-sweep模式下工作。同樣地,如果堆上的碎片變多,它切換回stop-and-copy模式。
JVM中還有很多額外的提速方法,比如just-in-time(JIT)compiler、HotSpot技術等。一部漫長的進化史啊:-)
ConstructorInitialization
There'sonethingtokeepinmind,however:Youaren'tprecludingtheautomaticinitialization,whichhappensbeforetheconstructorisentered.
所有的原生數據類型、對象引用(不包括局部變量,如果其未被初始化就使用的話,出現編譯錯誤:variablemightnothavebeeninitialized)和那些在定義處清晰初始化的變量都被預先初始化為零。
|_Orderofinitialization
在類內部,變量初始化的順序取決于它在類中定義的順序。變量的定義可能分散地貫穿在方法的定義之間,但是變量在構造函數執行前被初始化。
|_staticdatainitialization
靜態變量的初始化發生在類對象被創建的時候或者第一次靜態訪問發生的時候。
Tosummarizetheprocessofcreatinganobject,consideraclasscalledDog:
1、Eventhoughitdoesn'texplicitlyusethestatickeyword,theconstructorisactuallyastaticmethod.SothefirsttimeanobjectoftypeDogiscreated,orthefirsttimeastaticmethodorstaticfieldofclassDogisaccessed,theJavainterpretermustlocateDog.class,whichitdosebysearchingthroughtheclasspath.
2、AsDog.classisloaded(creatingaClassobject),allofitsstaticinitializersarerun.Thus,staticinitializationtakesplaceonlyonce,astheClassobjectisloadedforthefirsttime.
3、WhenyoucreateanewDog(),theconstructionprocessforaDogobjectfirstallocatesenoughstorageforaDogobjectontheheap.
4、Thisstorageiswipedtozero,automaticallysettingalltheprimitivesinthatDogobjecttotheirdefaultvalues(zerofornumberandtheequivalentforbooleanandchar)andthereferencestonull.
5、Anyinitializationsthatoccuratthepointoffielddefinitionareexecuted.
6、Constructorsareexecuted.Thismightactuallyinvolveafairamountofactivity,especiallywheninheritanceisinvolved.
|_Explicitstaticinitialization
Java中可以通過靜態代碼塊的方式初始化一組靜態變量。
語法形式:static{...}
它只會執行一次——thefirsttimeyoumakeanobjectofthatclassorthefirsttimeyouaccessastaticmemberofthatclass(evenifyounevermakeanobjectofthatclass).
|_Non-staticinstanceinitialization
Java提供一個簡單的語法{...},稱為實例初始化,用于初始化每個對象的非靜態的變量,在構造函數之前執行。
Arrayinitialization
Java通過拋出運行期異常的方式防止數組訪問越界,盡管這花費了一些時間,但是并沒有方式來關閉它。為了網絡安全和程序員的產出,Java設計者做出了他們認為值得的權衡。盡管你可能以你認為更高效的數組訪問方式來寫代碼,這也是浪費時間的,因為自動的編譯期和運行期優化將實現快速數組訪問。
|_Variableargumentlists
與數組作為參數不同,變參列表的參數個數可以是零。
(END_XPJIANG).
|
新聞熱點
疑難解答