Java爲什麼支持反射機制?

 學習心得:Java爲什麼支持反射機制?     選擇自 miaogang 的 Blog 

Java爲什麼能夠支持Reflection?答案是Java運行時仍然擁有類型信息,它包含了這個類一切:它有哪些字段、哪些方法,各是何種保護級別等等,還有這個類依賴於哪些類。在Java中,類信息以對象的形式存放,這些對象是一種元對象,它們的類型就是Class。擁有了這些信息,無論是動態創建對象還是調用某些方法都是輕而易舉的。在C++中,通過RTTI(運行時類型識別),我們也可以知道類的一些信息,但爲什麼C++中卻沒有Reflection,原因是類型信息不完整。RTTI這個名字本身就告訴我們,C++的類型信息是用來進行類型識別的,因此,它也不需要其它額外的信息。並不是C++無法做到這一點,而是C++不希望給用戶增加額外的負擔。有所得,必然有所失,因此,C++放棄了元對象。關於這一點,C++之父Bjarne Stroustrup在他的《C++語言的設計與演化》的14.2.8節中進行了深入的討論。

        元對象是Java Reflection的物質基礎,那它的精神基礎又是什麼呢?Java爲什麼要支持Reflection?經過上面的討論,我們把這個問題再進一步,爲什麼Java要提供元對象?

        討論這個問題,我們還要拉回到十年前,那時Java剛剛來到正式登上歷史的舞臺。Java實際上誕生在這之前的數年,那時候還叫Oak,環境所限使得這一劃時代的傑作甫一出爐便被束之高閣。當Netscape掀起了爲網絡大戲的序幕,Java得以鳳凰涅槃,這其中很重要的一個原因就是Java是以網絡爲中心的。

        仔細觀察,我們會發現,Java的整個基礎架構的設計都是爲網絡服務。首當其衝的便是Java中最著名的跨平臺。其實,在Java之前的年代,人們也需要考慮平臺之間的可移植性,但這種移植大多數集中在源碼一級,這也就是C語言可以流行的原因之一,在單機環境下,平臺的差異並不那麼明顯。網絡的出現使平臺之間差異凸現出來,因爲網絡可能會連接各種各樣的計算機和設備。沒錯,還有設備,你也許知道Java最初的開發是和嵌入式設備相關的。一旦應用可以跨平臺,程序開發和後期管理維護工作將得到極大的簡化,可移植性也從源碼級晉升到二進制級(Java字節碼)。所以,跨平臺實際上也是爲了網絡打基礎。Java中另一個重要的買點——安全性與網絡之間的關係更爲密切,誰都可以想出幾條理由,把二者關聯起來。
再來具體看看Java的基礎架構如何對網絡進行支持的。還記得Java最初是怎麼吸引人的嗎?沒錯,Applet。熟悉原理的朋友都知道,Applet的運行是把遠程的類文件下載到本地來執行的。相對於本地硬盤,網絡給我們的感覺就是一個字————慢。如果Java採用傳統可執行文件組織方式,即一個完整的可執行文件,把整個Applet下載下來的運行,只怕等到花兒也謝了。Java採用的手法是把文件拆開,以類爲單位進行組織,這就是我們今天見到的class文件。這樣,執行的過程就變成第一個類下載之後就可以運行,大大節省了最初的等待時間。好的設計會把程序分成若干的模塊,所以,絕大多數程序不可能寫在一個類中。因此,類文件中必須包含它所用到類。對於引導部分,我們可以讓它以特定的方式開始執行,比如把我們耳熟能詳的main方法放在特定的字節,但對於沒有定法的任意方法,是沒有辦法規定的,而一個類調用另一個類的方法就是這樣隨意,因此類文件中必須包含這個類方法的信息,進一步字段信息也會加進來,這樣幾乎一個完整類的信息就出來了,而這些信息對應的恰好是元對象。所以,元對象出現在Java基礎架構中。

        有了元對象,Reflection也成了一件順其自然的事情。有了Reflection,Java也就擁有了動態擴展的能力,這樣就可以極大的提高程序的靈活性。

        關於Java基礎結構對網絡的支持還可以再說幾句。class文件經過了精心的設計,本身相當緊湊,其目的就是爲了方便在網絡上傳輸,而JAR文件的出現,其目的也是爲了方便網絡傳輸,因爲如果每次只傳輸一個類,大量的時間都被浪費在建立網絡連接的過程中,JAR文件使得一次傳輸多個類成爲可能,而且我們還知道JAR文件中的數據是經過壓縮的,這樣可以進一步減少下載時間。Java基礎架構對網絡的支持,《深入Java虛擬機》(第二版)的4.3節進行了很好闡述,有興趣不妨看一下。

        對Reflection思考讓我有機會對Java本身的設計進行深入的思考。一個好的軟件設計需要一個核心理念作爲支撐,所有的一切都是圍繞核心進行的,而對於Java,這個核心就是網絡。

一次有趣的思考體驗!


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章