41.?instanceof與轉(zhuǎn)型
- System.out.println( null ? instanceof ?String); //false ??
- System.out.println( new ?Object()? instanceof ?String); //false ??
- //編譯能通過 ??
- System.out.println((Object)? new ?Date()? instanceof ?String); //false ??
- //!!程序不具有實際意義,但編譯時不能通過 ??
- //!!System.out.println(new?Date()?instanceof?String); ??
- //!!運行時拋ClassCastException,這個程序沒有任何意義,但可以編譯 ??
- //!!System.out.println((Date)?new?Object()); ??
null可以表示任何引用類型,但是instanceof操作符被定義為在其左操作數(shù)為null時返回false。
?
如果instanceof告訴你一個對象引用是某個特定類型的實例,那么你就可以將其轉(zhuǎn)型為該類型,并調(diào)用該類型的方法
,而不用擔心會拋出ClassCastException或NullPointerException異常。
?
instanceof操作符有這樣的要求:左操作數(shù)要是一個對象的或引用,右操作數(shù)是一個引用類型,并且這兩個操作數(shù)的
類型是要父子關系(左是右的子類,或右是左的子類都行),否則編譯時就會出錯。
42.?父類構(gòu)造器調(diào)用已重寫的方法
- public ? class ?P?{??
- ? private ? int ?x,?y;??
- ? private ?String?name;??
- ??
- ?P( int ?x,? int ?y)?{??
- ?? this .x?=?x;??
- ?? this .y?=?y;??
- ?? //?這里實質(zhì)上是調(diào)用子類被重寫的方法 ??
- ??name?=?makeName();??
- ?}??
- ??
- ? protected ?String?makeName()?{??
- ?? return ? "[" ?+?x?+? "," ?+?y?+? "]" ;??
- ?}??
- ??
- ? public ?String?toString()?{??
- ?? return ?name;??
- ?}??
- ??
- }??
- ??
- class ?S? extends ?P?{??
- ? private ?String?color;??
- ??
- ?S( int ?x,? int ?y,?String?color)?{??
- ?? super (x,?y);??
- ?? this .color?=?color;??
- ?}??
- ??
- ? protected ?String?makeName()?{??
- ?? return ? super .makeName()?+? ":" ?+?color;??
- ?}??
- ??
- ? public ? static ? void ?main(String[]?args)?{??
- ??System.out.println( new ?S( 1 ,? 2 ,? "red" )); //?[1,2]:null ??
- ?}??
- }??
?
在一個構(gòu)造器調(diào)用一個已經(jīng)被其子類重寫了的方法時,可能會出問題:如果子類重寫的方法要訪問的子類的域還未初
始化,因為這種方式被調(diào)用的方法總是在實例初始化之前執(zhí)行。要想避免這個問題,就千萬不要在父類構(gòu)造器中調(diào)用
已重寫的方法。
43.?靜態(tài)域與靜態(tài)塊的初始順序
- public ? class ?T?{??
- ? public ? static ? int ?i?=?prt();??
- ? public ? static ? int ?y?=? 1 ;??
- ? public ? static ? int ?prt()?{??
- ?? return ?y;??
- ?}??
- ??
- ? public ? static ? void ?main(String[]?args)?{??
- ??System.out.println(T.i); //?0 ??
- ?}??
- }??
上面的結(jié)果不是1,而是0,為什么?
?
類初始化是按照靜態(tài)域或靜態(tài)塊在源碼中出現(xiàn)的順序去執(zhí)行這些靜態(tài)初始器的(即誰先定義,就先初始化誰),上現(xiàn)程序中由于i先于y聲明,所以先初始化i,但由于i初始化時需要由y來決定,此時y又未初始化,實為初始前的值0,所以i的最后結(jié)果為0。
44.?請使用引用類型調(diào)用靜態(tài)方法
- public ? class ?Null?{??
- ? public ? static ? void ?greet()?{??
- ??System.out.println( "Hello?world!" );??
- ?}??
- ??
- ? public ? static ? void ?main(String[]?args)?{??
- ??((Null)? null ).greet();??
- ?}??
- }??
上面程序運行時不會打印NullPointerException異常,而是輸出"Hello world!",關鍵原因是:調(diào)用靜態(tài)方法時將忽略前面的調(diào)用對象或表達示,只與對象或表達式計算結(jié)果的類型有關。
?
在調(diào)用靜態(tài)方法時,一定要使用類去調(diào)用,或是靜態(tài)導入后直接使用。
45.?循環(huán)中的不能聲明局部變量
- for ?( int ?i?=? 0 ;?i?<? 1 ;?i++)???
- ?Object?o?;? //!!?編譯不能通過 ??
- ??
- for ?( int ?i?=? 0 ;?i?<? 1 ;?i++)???
- ?Object?o?=? new ?Object();? //!!?編譯不能通過 ??
?
一個本地變量聲明看起來像是一條語句,但是從技術上來說不是。
?
Java語言規(guī)范不允許一個本地變量聲明語句作為一條語句在for、while或do循環(huán)中重復執(zhí)行。
?
一個本地變量聲明作為一條語句只能直接出現(xiàn)在一個語句塊中(一個語句塊是由一對花 括號以及包含在這對花括號中的語句和聲明構(gòu)成的):
- for ?( int ?i?=? 0 ;?i?<? 1 ;?i++)?{??
- ?Object?o?=? new ?Object();? //?編譯OK ??
- }??
?
46.?內(nèi)部類反射
- public ? class ?Outer?{??
- ? public ? class ?Inner?{??
- ?? public ?String?toString()?{??
- ??? return ? "Hello?world" ;??
- ??}??
- ?}??
- ? public ? void ?getInner()?{??
- ?? try ?{??
- ??? //?普通方式創(chuàng)建內(nèi)部類實例 ??
- ???System.out.println( new ?Outer(). new ?Inner()); //?Hello?world ??
- ??? //!!?反射創(chuàng)建內(nèi)部類,拋異常:java.lang.InstantiationException:Outer$Inner ??
- ???System.out.println(Inner. class .newInstance());??
- ??}? catch ?(Exception?e)?{??
- ??}??
- ?}??
- ? public ? static ? void ?main(String[]?args)?{??
- ??? new ?Outer().getInner();??
- ?}??
- }??
上面因為構(gòu)造內(nèi)部類時外部類實例不存在而拋異常。
?
一個非靜態(tài)的嵌套類的構(gòu)造器,在編譯的時候會將一個隱藏的參數(shù)作為它的第一個參數(shù),這個參數(shù)表示它的直接外圍實例。如果使用反射創(chuàng)建內(nèi)部類,則要傳遞個隱藏參數(shù)的唯一方法就是使用java.lang.reflect.Constructor:
- Constructor?c?=?Inner. class .getConstructor(Outer. class ); //獲取帶參數(shù)的內(nèi)部類構(gòu)造函數(shù) ??
- System.out.println(c.newInstance(Outer. this )); //反射時還需傳進外圍類 ??
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
