Java編程思想——第十四章:類型信息

運行時類型信息使得你可以在程序運行時發(fā)現(xiàn)和使用類型信息。

Java讓我們能在運行時識別對象和類的信息的兩種方式:

  1. 傳統(tǒng)的RTTI:它假定我們在編譯時已經(jīng)知道了所有的類型;
  2. 反射機制:它允許我們在運行時發(fā)現(xiàn)和使用類信息胚股。

1.為什么需要RTTI

  • 當把 Shape 對象放入 List<Shape>的數(shù)組時會向上轉(zhuǎn)型。但在向上轉(zhuǎn)型為 Shape 的時候也丟失了 Shape對象 的具體類型释树。對于數(shù)組而言削祈,它們只是 Shape 類的對象。

    當從數(shù)組中取出元素時肮砾,這種容器—實際上他將所有的事物當作 Object 持有—會自動將結(jié)果轉(zhuǎn)型回 Shape 诀黍。這是RTTI最基本的使用形式,因為在Java中仗处,所有類型轉(zhuǎn)換都是在運行時進行正確性檢查的眯勾。

    接下來就是多態(tài)機制的事情了枣宫,Shape 對象實際執(zhí)行什么樣的代碼,是由引用所指向的具體對象 Circle 吃环、SquareTriangle 而決定的也颤。你希望大部分代碼盡可能地了解對象的具體類型,而是只與對象家族的一個通用表示打交道郁轻。

2.Class對象

Class對象就是用來創(chuàng)建類的所有的常規(guī)對象翅娶。

類似程序的一部分,每一個類都有一個Class對象范咨。為了生成這個類的對象故觅,運行這個程序的Java虛擬機將使用被稱為 類加載器 的子系統(tǒng)。

Class.forName() 可以獲取Class對象的引用渠啊。getName()產(chǎn)生全限定的類名,并分別使用 getSimpleName()getCanonicalName() 來產(chǎn)生不含包名的類名和全限定名权旷。isInterface() 可以告訴你這個Class對象是否表示某個接口替蛉。還可以使用 getSuperclass() 方法查詢其直接基類。

2.1 類字面常量
  • 使用字面常量也可以生成對Class對象的引用

    FancyToy.class
    

    類字面常量不僅可以應(yīng)用于普通的類拄氯,也可以應(yīng)用于接口躲查、數(shù)組以及基本數(shù)據(jù)類型。

    當使用 .class 來創(chuàng)建對Class對象的引用時译柏,不會自動地初始化該Class對象镣煮。為使用類而做的準備工作實際包含三個步驟:

    1. 加載:這是由類加載器執(zhí)行的;
    2. 鏈接:在鏈接階段將驗證類中的字節(jié)碼鄙麦,為靜態(tài)域分配存儲空間典唇,并且如果必須的話,將解析這個類創(chuàng)建的對其他類的所有引用胯府。
    3. 初始化:如果該類具有超類介衔,則對其初始化,執(zhí)行靜態(tài)初始化其和靜態(tài)初始化塊骂因。
  • Class.forName() 會立即執(zhí)行初始化炎咖;

2.2 泛化的Class引用
  • Class引用總是指向某個Class對象,它可以制造類的示例寒波,并包含可作用與這些實例的所有方法代碼乘盼。它還包含該類的靜態(tài)成員,因此俄烁,Class引用表示的就是它所指向的對象的確切類型绸栅。而該對象便是Class類的一個對象。

    盡管泛型類引用只能賦值為指向其聲明的類型猴娩,但是普通類引用可以被重新賦值為指向任何其他的Class對象阴幌。通過泛型語法可以讓編譯器強制執(zhí)行額外的類型檢查勺阐。

  • 使用通配符 ? 放松限制,?代表任何事物矛双。

    Class<?> intClass = int.class;
    

    限定創(chuàng)建Class引用的范圍

    Class<? extends Numner> bounded = int.class;
    Class<? super FancyToy> up = ftClass.getSuperclass();
    
  • newInstance() 返回的不是精確類型渊抽,而只是Object。

2.3 新的轉(zhuǎn)型語法
  • cast()用于Class引用的轉(zhuǎn)型語法议忽,新的轉(zhuǎn)型語法對于無法使用普通轉(zhuǎn)型的情況顯得非常有用懒闷。

3.類型轉(zhuǎn)換前先做檢查

RTTI的第三種形式,就是關(guān)鍵字 instanceof栈幸。它返回一個布爾值愤估,告訴我們對象是不是某個特定類型的實例。

3.1 使用類字面量
3.2 動態(tài)的 instanceof
  • Class.isInstance 方法提供了一種動態(tài)地測試對象的途徑速址。
3.3 遞歸計數(shù)

4 注冊工廠

  • 使用 工廠方法 設(shè)計模式玩焰,將對象的創(chuàng)建工作交給類自己去完成。

5.instanceof與Class的等價性

6.反射:運行時的類信息

  • 如果不知道某個對象的確切類型芍锚,RTTI可以告訴你昔园。但這個類型在編譯時必須已知。
  • 人們想要在運行時獲取類的信息的另一動機并炮,便是希望提供在跨網(wǎng)絡(luò)的遠程平臺上創(chuàng)建和運行對象的能力默刚。這種被稱為遠程方法調(diào)用,它允許一個Java程序?qū)ο蠓植嫉蕉嗯_機器上逃魄。
  • RTTI和反射之間真正的區(qū)別在于:對于RTTI來說荤西,編譯器在編譯時打開和檢查 .class 文件。而對于反射機制來說伍俘,在運行時打開和檢查 .class 文件邪锌。

7.動態(tài)代理

  • Java的動態(tài)代理比代理的思想更向前邁進一步,因為它可以動態(tài)創(chuàng)建代理并動態(tài)地處理對所代理方法的調(diào)用养篓。在動態(tài)代理上所做的所有調(diào)用都會被重定向到單一的調(diào)用處理器上秃流,它的工作室揭示調(diào)用的類型并確定相應(yīng)的對策。

8.空對象

空對象最有用支出在于它更靠近數(shù)據(jù)柳弄,因為對象表示的是問題空間內(nèi)的實體舶胀。

8.1 模擬對象與樁
  • 空對象的邏輯變體是模擬對象和樁。與空對象一樣碧注,它們都表示在最終的程序中所使用的實際對象嚣伐。

    模擬對象和樁之間的差異在于程度不同。模擬對象往往是輕量級和自測試的萍丐,通常很多模擬對象被創(chuàng)建出來是為了處理各種不同的測試情況轩端。樁只是返回樁數(shù)據(jù),它通常是重量級的逝变。

9.接口與類型信息

  • interface關(guān)鍵字的一種重要目標就是允許程序員隔離構(gòu)建基茵,進而降低耦合性奋构。如果你編寫接口,那么就可以實現(xiàn)這一目標拱层,但是通過類型信息弥臼,這種耦合性還是會傳播出去——接口并非是對解耦的一種無懈可擊的保障。最簡單的解決方式是對實現(xiàn)使用包訪問權(quán)限根灯。



06/06/2019 :created
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末径缅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子烙肺,更是在濱河造成了極大的恐慌纳猪,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桃笙,死亡現(xiàn)場離奇詭異氏堤,居然都是意外死亡,警方通過查閱死者的電腦和手機搏明,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門丽猬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人熏瞄,你說我怎么就攤上這事∶裕” “怎么了强饮?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長为黎。 經(jīng)常有香客問我邮丰,道長,這世上最難降的妖魔是什么铭乾? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任剪廉,我火速辦了婚禮,結(jié)果婚禮上炕檩,老公的妹妹穿的比我還像新娘斗蒋。我一直安慰自己,他們只是感情好笛质,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布泉沾。 她就那樣靜靜地躺著,像睡著了一般妇押。 火紅的嫁衣襯著肌膚如雪跷究。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天敲霍,我揣著相機與錄音俊马,去河邊找鬼丁存。 笑死,一個胖子當著我的面吹牛柴我,可吹牛的內(nèi)容都是我干的解寝。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼屯换,長吁一口氣:“原來是場噩夢啊……” “哼编丘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起彤悔,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤嘉抓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后晕窑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抑片,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年杨赤,在試婚紗的時候發(fā)現(xiàn)自己被綠了敞斋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡疾牲,死狀恐怖植捎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阳柔,我是刑警寧澤焰枢,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站舌剂,受9級特大地震影響济锄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜霍转,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一荐绝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧避消,春花似錦低滩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至均驶,卻和暖如春昏兆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背妇穴。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工爬虱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留隶债,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓跑筝,卻偏偏與公主長得像死讹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子曲梗,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容