回覆列表
  • 1 # 架構師小林

    反射不需要你主動去new物件,直接根據類全名就可以例項化物件,這在寫各種框架上面很方便,比如一開始的spring 配置檔案模式就是直接在配置檔案裡指定類全名即可

  • 2 # 大偉奇妙生活

    Java的反射機制是Java特性之一,反射機制是構建框架技術的基礎所在。靈活掌握Java反射機制,對大家以後學習框架技術有很大的幫助。

    什麼是Java的反射?

    反射是Java的特徵之一,是一種間接操作目標物件的機制。

    JAVA反射機制是在執行狀態中,對於任意一個實體類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意方法和屬性;這種動態獲取資訊以及動態呼叫物件方法的功能稱為java語言的反射機制。

    Java反射有什麼作用?

    透過反射可以使程式程式碼訪問裝載到JVM 中的類的內部資訊

    ● 獲取已裝載類的成員變數資訊

    ● 獲取已裝載類的方法

    ● 獲取已裝載類的構造方法資訊

    反射的應用場合:

    在編譯時根本無法知道該物件或類可能屬於哪些類,程式只依靠執行時資訊來發現該物件和類的真實資訊。

    反射的缺點

    效能問題

    使用反射基本上是一種解釋操作,用於欄位和方法接入時要遠慢於直接程式碼。因此Java反射機制主要應用在對靈活性和擴充套件性要求很高的系統框架上,普通程式不建議使用。

    使用反射會模糊程式內部邏輯

    程式人員希望在原始碼中看到程式的邏輯,反射等繞過了原始碼的技術,因而會帶來維護問題。反射程式碼比相應的直接程式碼更復雜

  • 3 # 急速馬力快de原始碼控

    一,定義

    Java反射機制是在執行狀態中,對於任意一個類,都能夠知道它的屬性和方法;對於任意一個物件,都能夠呼叫它的屬性和方法。這種動態獲取資訊以及動態呼叫物件方法的功能被稱為Java語言的反射機制。

    二,用途

    在Java程式執行過程中,獲取任意需要的類和物件的資訊。

    三,舉例:透過反射在執行時讀取註解資訊

    Java中,Package、Class、Constructor、Method、Field都實現了一個介面AnnotatedElement,宣告在java.lang.reflect反射包中,有如下方法:

    四,程式碼實現

    1,宣告一個註解

    @Retention(RetentionPolicy.RUNTIME)public @interface HelloAnnotation { String value() default "Hello Annotation!";}

    2,引用註解

    @HelloAnnotation("Hello Bean!")public class HelloBean {}

    3,執行時呼叫反射獲取註解

    public class HelloClassTest { @Test public void testClass() throws NoSuchMethodException { Class<?> clazz = HelloClass.class; HelloAnnotation annotation = clazz.getAnnotation(HelloAnnotation.class); System.out.println(String.format("類: %s, 註解: %s, 值:%s", clazz.getSimpleName(), annotation.annotationType().getSimpleName(), annotation.value() )); }}

    4,執行程式輸出資訊

  • 4 # 通訊人的自我修養

    簡單的來說,反射機制其實就是指程式在執行的時候能夠獲取自身的資訊。如果知道一個類的名稱或者它的一個例項物件, 就能把這個類的所有方法和變數的資訊(方法名,變數名,方法,修飾符,型別,方法引數等等所有資訊)找出來。如果明確知道這個類裡的某個方法名+引數個數 型別,還能透過傳遞引數來執行那個類裡的那個方法,這就是反射。

    在Java中,Class類與java.lang.reflect類庫一起對反射的概念提供了支援,該類庫包含了Field、Method以及Constructor類(每個類都實現了Member介面)。我們知道對RTTI(執行時型別識別)來說,編譯器在編譯時開啟和檢查.class檔案。而對於反射機制來說,.class檔案在編譯時是不可獲取的,所以是在執行時開啟和檢查.class檔案的。

    這個是比較簡單的說法,真正解釋起來幾篇文章也說不完,聯絡題主搜下相關技術部落格,相關介紹還是很多的。

  • 5 # 程式碼接盤俠

    Java反射說的是在執行狀態中,對於任何一個類,我們都能夠知道這個類有哪些方法和屬性。對於任何一個物件,我們都能夠對它的方法和屬性進行呼叫。我們把這種動態獲取物件資訊和呼叫物件方法的功能稱之為反射機制。

    可以不透過new關鍵字獲取物件並且使用類物件中的成員變數,方法,修飾符等等,在這裡舉例獲取類。

    第一種:使用Class.forName(String classPath) ClassPath:寫需要反射的類名,一般是以包名.類名。如:Class clazz = Class.forName("com.entity.Example");

    第二種:直接使用Class clz = 類名.class

    這種情況一般在我們知道有這個類的時候去使用。如:Class clz = Example.class;

    第三種:Class clz = 物件. getClass();

    前提是物件已經被例項化出來了 。如:

    Example ex = new Example();

    Class clz = ex.getClass();

    這三種方法都有各自的優點,一般我們使用第一種比較多,按照自己的實際需求去使用才是最好的。反射有啥用?有啥應用場景?

    1.spring框架的ioc是基於java的反射機制。

    2.JDBC 的資料庫的連線註冊驅動,獲取連線也是基於Java反射。

    3.Hibernate,Mybatis都有運用到反射。

  • 6 # 一一哥Sun

    反射技術,可以說是java開發裡的一大利器,很多的orm框架,ioc框架,原始碼內部都會用到反射技術。尤其是反射加註解,兩者結合,可以做很多工作。反射一般是作用在執行時階段,透過拿到位元組碼,進行反向操作。我們可以透過java的反射技術,動態的拿到我們想要的類中的很多資訊。

  • 7 # 你看我獨角獸嗎

    反射所需的類在java.lang.reflect包下提供。反射為我們提供了有關物件所屬類的資訊,以及可以使用該物件執行的該類的方法。透過反射,我們可以在執行時呼叫方法,而與它們所使用的訪問說明符無關。反射可用於獲取有關一些的有用資訊 getClass()方法用於獲取物件所屬的類的名稱。建構函式 getConstructors()方法用於獲取物件所屬類的公共建構函式。方法 getMethods()方法用於獲取物件所屬類的公共方法。簡單的例子

    為了先清楚下反射的用處,我們將看一個非常基本的示例,該示例在執行時檢查簡單Java物件的欄位。

    讓我們建立一個簡單的Person類,其中僅包含name和age欄位,而根本不包含任何方法。這是Person類:

    現在,我們將使用Java反射來發現此類所有欄位的名稱。為了欣賞反射的力量,我們將構造一個Person物件並將Object作為引用型別:

    這個測試告訴我們,我們能夠得到的陣列Field物件從我們人的物件,即使參考物件是物件的父類。

    在上面的示例中,我們僅對這些欄位的名稱感興趣,但是還有很多事情可以做,我們將在後續部分中看到更多示例。

    注意我們如何使用一個輔助方法來提取實際的欄位名,這是一個非常基本的程式碼:

    重點觀察如果知道方法的名稱和引數型別,則可以透過反射呼叫該方法。為此,我們使用以下兩種方法getDeclaredMethod():建立要呼叫的方法的物件。該方法的語法是Class.getDeclaredMethod(名稱,引數型別)name-要建立其物件的方法的名稱parametertype-引數是Class物件的陣列

    invoke():要在執行時呼叫類的方法,我們使用以下方法——

    Method.invoke(物件,引數)如果類的方法不接受任何方法 引數,然後將null用作引數。透過反射,我們可以在類的類物件的幫助下訪問類的私有變數和方法,並透過使用物件來呼叫方法,如上所述。為此,我們使用以下兩種方法。

    Class.getDeclaredField(FieldName):用於獲取私有欄位。返回指定型別欄位名稱的欄位型別的物件。Field.setAccessible(true): 允許訪問該欄位,而與該欄位使用的訪問修飾符無關。

    使用發射的優勢可擴充套件性功能:應用程式可以透過使用其完全限定的名稱建立可擴充套件性物件的例項來使用外部的使用者定義類。除錯和測試工具:偵錯程式使用反射的屬性檢查類的私有成員。缺點效能開銷:反射操作比非反射操作的效能要慢,因此應避免在對效能敏感的應用程式中經常呼叫的程式碼段中避免這樣做。內部曝光:反射程式碼破壞了抽象,因此可能會隨著平臺升級而改變行為。

  • 8 # 果蔬烘乾機

    Java的反射機制簡單來說就是程式執行的時候能夠獲取自身的資訊。只要給定類的名字,就可以透過反射機制來獲得類的所有資訊。

    比如說Class.forName("com.mysql.jdbc.Driver.class").newlnstance();生成驅動物件實列。這個就是反射。

    比如說編寫訪問資料庫時有了Java反射機制,只需要寫一個dao類,四個方法,增刪改查,傳入不同的物件,就可以了。而不用每一個表都建立一個dao類,反射機制會自動完成剩下的事情。專門做那些重複的有規則的事情。

    比如說用反射機制實現對資料庫資料的增查。

    先定規則,資料庫的每一個表物件一個pojo類,表中的每一個欄位對應pojo類中的一個屬性,類的名字和表的名字相同。

    為pojo類的每一個屬性新增標準的set和get方法。

    然後就可以書寫程式碼了,由於反射的靈活性很高,我們沒有必要把精力放在操作程式碼,方法更多時間放在邏輯功能上。可以減少開發時間,程式碼可讀性好。

  • 9 # 程式猿W
    反射的功能

    在執行時判斷任意一個物件所屬的類

    在執行時構造任意一個類的物件

    在執行時判斷任意一個類所具有的成員變數和方法

    在執行時呼叫任意一個物件的方法

    Class類

    獲得類相關的方法

    getClassLoader():獲得類的載入器

    forName(String className):根據類名返回類的物件

    getName():獲得類的完整路徑名字

    newInstance():建立類的例項

    getPackage():獲得類的包

    getSimpleName():獲得類的名字

    getInterfaces():獲得當前類實現的類或是介面

    getSuperclass():獲得當前類繼承的父類的名字

    2. 獲得類中屬性相關的方法

    getField(String name): 獲得某個公有的屬性物件

    getFields(): 獲得所有公有的屬性物件

    getDeclaredField(String name):獲得某個屬性物件

    getDeclaredFields():獲得所有屬性物件

    注意: getFields() 和 getDeclaredFields() 的區別??

    3.獲得類中註解相關的方法

    getAnnotation(Class<A> annotationClass): 返回該類中與引數型別匹配的公有註解物件

    getAnnotations(): 返回該類所有的公有註解物件

    getDeclaredAnnotation(Class<A> annotationClass):返回該類中與引數型別匹配的所有註解物件

    getDeclaredAnnotations(): 返回該類所有的註解物件

    4. 獲得類中構造器相關的方法

    getConstructor(Class...<?> parameterTypes):獲得該類中與引數型別匹配的公有構造方法

    getConstructors():獲得該類的所有公有構造方法

    getDeclaredConstructor(Class...<?> parameterTypes):獲得該類中與引數型別匹配的構造方法

    getDeclaredConstructors(): 獲得該類所有構造方法

    5.獲得類中方法相關的方法

    getMethod(String name, Class...<?> parameterTypes): 獲得該類某個公有的方法

    getMethods(): 獲得該類所有公有的方法

    getDeclaredMethod(String name, Class...<?> parameterTypes):獲得該類某個方法

    getDeclaredMethods():獲得該類所有方法

    Field類 -代表類的成員變數,

    equals(Object obj): 屬性與obj相等則返回true

    get(Object obj):獲得obj中對應的屬性值

    set(Object obj, Object value):設定obj中對應屬性值

    Method類

    invoke(Object obj,Object args[]): 傳遞object物件及引數呼叫該物件對應的方法

    Constructor類

    newInstance(Object... initargs): 根據傳遞的引數建立類的物件

    獲取對應類的Class物件

    Class.forName("java.lang.String")

    使用類的.class語法: String.class

    使用物件的getClass()方法,String s = "aa";Class<?> clazz = s.getClass();

    透過類的不帶引數的構造方法生成物件

    先獲取Class物件,然後透過該Class物件的newInstance()方法直接生成即可

    Class<?> classType = String.class;

    Object obj = classType.newInstance();

    2.先獲取Class物件,然後透過該物件獲得對應的Constructor物件,再透過該Constructor物件的newInstace()方法生成

    Class<?> classType = String.class;

    Constructor cons = classType.getConstructor(new Class[]{});

    Object obj = cons.newInstance(new Object[]{})

    3.透過帶引數的構造方法

    Class<?> classType = String.class;

    Constructor cons = classType.getConstructor(new Class[]{String.class,int.class});

    Object obj = cons.newInstance(new Object[]{"hello",3})

    下面用反射+ 註解 實現類似於Spring IOC功能

    1.獲取指定包名下的所有Class 物件

    2. 初始化Bean容器

    private static Map<Class<?>,Object> beanMap = new HashMap<Class<?>, Object>();

    3.實現類的依賴注入

    獲取第二步實現 Map<Class<?>,Object> beanMap = BeanHelper.getBeanMap();

  • 中秋節和大豐收的關聯?
  • 焦慮症一般多長時間會變成憂鬱症?