日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java反射机制Reflection

發(fā)布時間:2024/8/26 java 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java反射机制Reflection 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java反射機制

  • 1 .class文件
  • 2 Class類
  • 3 Class類與反射機制
  • 4 Java反射機制的類庫支持及簡介
  • 5 反射機制的定義與應(yīng)用
  • 6?反射機制Demo
    • Java反射機制demo(一)—實例化Class對象,并獲得其他類包名和類型
    • Java反射機制demo(二)—通過Class實例化任意類的對象
    • Java反射機制demo(三)—獲取類中的構(gòu)造函數(shù)
    • Java反射機制demo(四)—獲取一個類的父類和實現(xiàn)的接口
    • Java反射機制demo(五)—獲得并調(diào)用一個類中的方法?
    • Java反射機制demo(六)—獲得并操作一個類的屬性
    • Java反射機制demo(七)—反射機制與工廠模式

了解Java的反射機制,首先要從RTTI開始。

文章的一開頭就開始裝逼了,RTTI是個什么東西。RTTI英文全稱:Run-Time?Type?Information,望文生義,RTTI是運行時類型信息。

什么是RTTI,有什么作用,編程時會用到嗎?這個問題先放在這里,等會再解答。

?

1, ?.class文件

學過一點點Java的人,都知道Java文件在編譯之后變成了class文件。問題又來了,class文件是什么?肯定有人回答:Class文件就是一個編譯后的文件,就像C/C++.c.cpp文件編譯之后編程了.o,還需要解釋嗎?要,必須要。

先來一張class文件的文件格式示意圖。

??

?

沒看懂?必然看不懂,先簡單介紹一下Class文件。

Class文件從文件類型上是二進制文件,問題又來了,什么是二進制文件?二進制文件就是機器能讀懂的語言,自從馮諾依曼的原型機出世,所有的計算機作為它的后代就只認識10這兩個數(shù)字。二進制文件就是一堆01Class文件就是由一堆01堆起來的。但是,無規(guī)矩不成方圓,這些01是按照某種嚴格的規(guī)則放置在對應(yīng)的位置上。JVM作為Java的運行環(huán)境,是規(guī)則的制定者和解讀者(盡管是Java的開發(fā)者們制定的,我們可以簡單地認為JVM做了這些事情,至少是開發(fā)者們讓JVM這么干的)。JVM按照規(guī)則來解讀01序列,然后告訴計算機如何去執(zhí)行我們的程序所表達的意愿。

但是,Class文件的結(jié)構(gòu)不像XML那些描述型語言那樣松散和自由,它的定義是非常嚴格的,條件也非常的苛刻。Class文件沒有任何的分割符號,哪怕是一個空格一個回車(關(guān)于回車為什么叫做回車,點擊這里)。

在圖中Class文件的幾個部分,HeaderConstant?pool...等,這些數(shù)據(jù)項無論是順序還是數(shù)量都是被嚴格限定的,哪個字節(jié)代表什么含義,長度是多少,先后順序如何都被非常苛刻地限制,不允許改變。然后,你會看到Class?attributesclass文件的最后,應(yīng)該用過Java反編譯器吧,有沒有注意過Java反編譯器反編譯的class文件方法在上面,屬性都在下面,就是這個原因。

?

這篇博客講解的很詳細,http://blog.csdn.net/dc_726/article/details/7944154。

文件的開頭是Header,這段十六進制碼表明了JDK的版本號,所以你把JDK1.7class文件放在JDK1.6的環(huán)境下就不能運行,向下兼容。

?

2, Class

扯得有點遠了。回到正題。

Java被編譯后,生成了.class文件,JVM此時就要去解讀.class文件。當程序主動去使用某個類時,如果這個類還沒有被加載到內(nèi)存中,JVM會通過三個步驟對類進行初始化:

1.加載:由類加載器執(zhí)行,該步驟查找字節(jié)碼,并從這些字節(jié)碼中創(chuàng)建一個Class對象

2.鏈接:在鏈接階段將驗證類中的字節(jié)碼,為靜態(tài)域分配存儲空間,并且如果必須的話,將解析這個類創(chuàng)建的對其他類的所有引用。

3.初始化:如果該類有超類,則對其初始化,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化塊。

如以上三步,一個.class文件被融入到程序中供其調(diào)用。第一個步驟中,查找字節(jié)碼并生成一個Class對象,在Java中,如Thinking?in?Java中提到的,一切皆是對象。被編譯后的Java文件.class也被JVM解析為一個對象,這個對象就是java.lang.Class

?

這樣當程序在運行時,每個java文件就最終變成了Class類對象的一個實例。我們通過Java的反射機制應(yīng)用到這個實例,就可以去獲得甚至去添加改變這個類的屬性和動作,使得這個類成為一個動態(tài)的類(所謂的動態(tài)是按照動態(tài)語言的定義——在程序運行時改變其結(jié)構(gòu):心得函數(shù)可以被引進,已有的函數(shù)可以被刪除等在結(jié)構(gòu)上的變化)。?由此,可以看出反射機制使得Java語言多么靈活。

?

3,Class類與反射機制

Class類的概念盡管很抽象,但是無疑,它是反射機制的起源,是Java語言中一個精巧美妙地設(shè)計。

介紹完.class文件是怎么回事,又簡單說明了.classClass之間的關(guān)系,然后要看一下Class類的官方描述。

官方文檔是最權(quán)威的,先來看一下Class類中的API是如何描述Class類的。下面是翻譯后的中文文檔的描述:

Class類的實例表示正在運行的Java應(yīng)用程序的類和接口。枚舉是一種類,注釋(注解)是一種接口。每個數(shù)組屬于被映射為Class對象的一個類,所有具有相同元素類型和維數(shù)的數(shù)組都共享該Class對象。基本的Java類型(booleanbytecharshortintlongfloat?和?double)和關(guān)鍵字?void?也表示為?Class?對象。Class沒有公用構(gòu)造方法。Class對象是在加載類時由JVM以及通過調(diào)用類加載器中的defineClass方法自動構(gòu)造的。

看完這個描述,并結(jié)合上面提到的三個步驟,應(yīng)該會有更好的理解。

?4,反射機制的定義和應(yīng)用

在深入到反射機制之前,先探析一下反射機制的定義和應(yīng)用。反射機制定義:Java反射機制是在運行狀態(tài)時,對于任意一個類,都能夠直到這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性。

我們不禁會想,得到這些屬性和方法并且去改變它們有什么用?覺得反射機制仿佛很遙遠,但是作為一個全職程序員,除了假期和雙休日,你幾乎每天都在和反射機制打交道,無論你使用的Eclipse系列的IDE(集成開發(fā)環(huán)境),還是使用的目前較為流行的IntelliJ?IDEA,又或者是NetBeans,在你輸入一個對象的名稱,按下”.”時,總會彈出這個對象所擁有的所有方法列表供選擇。這個功能就是反射機制實現(xiàn)的,反射機制得到了這個對象的方法和屬性。

很顯然,是先有的反射機制,才有的自動智能提示,所以上面的例子只能勉強算作反射機制出現(xiàn)和應(yīng)用的一個動機。

在反射機制設(shè)計之初,睿智的設(shè)計者們或許就有了分布式的野心。編程人員希望Java能夠提供在跨網(wǎng)絡(luò)的遠程平臺上創(chuàng)建和運行對象的能力,這種能力的名字大家應(yīng)該很熟悉,叫做遠程方法調(diào)用RMI,這便是編程人員想要在運行時獲取類的信息的又一個動機。RMI允許一個Java程序?qū)ο蠓植嫉蕉嗯_機器上,即在遠程就可以調(diào)用某個對象,就像你通過瀏覽器去使用別人提供的網(wǎng)頁服務(wù)一樣。這就促成了現(xiàn)在的分布式系統(tǒng)的崛起。然而在JDK1.1版本中,Java反射機制就出現(xiàn)了。

?

5,Java反射機制的類庫支持及簡介

Class類和java.lang.reflect類庫一起構(gòu)成了對Java反射機制的支持。其中最常使用到的類是ConstructorFieldMethod,而這三個類都繼承了一個接口java.lang.reflect.Member。下面列舉介紹一下java.lang.reflect類庫中的類:

  • AccessibleObjectFieldMethod,和Constructor對象的基類。提供了將反射的對象標記為在使用時取消默認Java語言訪問控制檢查的能力。
  • Array:提供了動態(tài)創(chuàng)建和訪問Java數(shù)組的方法。
  • Constructor:提供關(guān)于類的單個構(gòu)造方法的信息以及對它的訪問權(quán)限。
  • Field:?提供有關(guān)類或接口的單個字段的信息,以及對它的動態(tài)訪問權(quán)限。反射的字段可能是一個類(靜態(tài))字段或?qū)嵗侄巍?/span>
  • Method:?提供關(guān)于類或接口上單獨某個方法(以及如何訪問該方法)的信息。所反映的方法可能是類方法或?qū)嵗椒?#xff08;包括抽象方法)。
  • Modifier:?類提供了?static?方法和常量,對類和成員訪問修飾符進行解碼。修飾符集被表示為整數(shù),用不同的位位置?(bit?position)?表示不同的修飾符。該類的字段均是int類型的變量。?
  • Proxy:?提供用于創(chuàng)建動態(tài)代理類和實例的靜態(tài)方法,它還是由這些方法創(chuàng)建的所有動態(tài)代理類的超類。
  • ReflectPermission:反射操作的?Permission?類。ReflectPermission?是一種指定權(quán)限,沒有動作。當前定義的唯一名稱是?suppressAccessChecks,它允許取消由反射對象在其使用點上執(zhí)行的標準?Java?語言訪問檢查?-?對于?publicdefault(包)訪問、protectedprivate?成員。

?

當要使用反射機制去探查一個類的內(nèi)部時,還可以調(diào)用getFields()getMethods()getConstructors()等很便利的方法。對于反射機制,和RTTI的區(qū)別就在于,RTTI是在編譯時打開和檢查.class文件,而反射機制是在運行時打開和檢查.class文件。

?

6,反射機制使用Demo

1.Class類是反射機制的起源,我們得到Class類對象有三種方法:

Class.forName()Object.getClass()類字面常量xx.class

  

解釋一下這三種方法,

  • 第一種方法是Class類自帶的方法,
  • 第二種方法是所有的對象都能夠使用的方法,因為getClass()方法是Object類的方法,所有的類都繼承了Object,因此所有類的對象也都具有getClass()方法。
  • 第三種方法是類字面常量。Thinking?in?Java中建議使用類字面常量來生成對Class對象的引用,這樣做即簡單又安全,因為在編譯時就會受到檢查,因此不需要置于try語句塊中,并且它根除了對forName()方法的調(diào)用,所以也更高效。可以想象一下JDBC的語法,在加載驅(qū)動的時候,使用的就是forName()方法,因此即使單獨這一句程序,也要使用try語句塊。

類字面常量使得創(chuàng)建Class對象的引用時不會自動地初始化該對象,而是按照之前提到的加載,鏈接,初始化三個步驟,這三個步驟是個懶加載的過程,不使用的時候就不加載,這種機制是C/C++無法復制模擬的。

?

其他DEMO

?

  • Java反射機制demo(一)—實例化Class對象,并獲得其他類包名和類型
  • Java反射機制demo(二)—通過Class實例化任意類的對象?
  • Java反射機制demo(三)—獲取類中的構(gòu)造函數(shù)
  • Java反射機制demo(四)—獲取一個類的父類和實現(xiàn)的接口
  • Java反射機制demo(五)—獲得并調(diào)用一個類中的方法?
  • Java反射機制demo(六)—獲得并操作一個類的屬性

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/AaronCui/p/4911123.html

總結(jié)

以上是生活随笔為你收集整理的Java反射机制Reflection的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。