1. 程式人生 > >java(19)---反射機制

java(19)---反射機制

java---反射機制

java語言允許通過程式化的方式間接對Class進行操作,Class檔案由類載入器裝載後,在JVM中形成一份描述Class結構的元資訊物件,通過該元資訊物件可以獲知Class的結構資訊:如

建構函式、屬性和方法等。

java允許使用者藉由這個Class相關的元資訊對物件間接呼叫Class物件的功能。

11.1、什麼是反射?

反射機制是在執行狀態中:

對於任意的一個類,都能夠知道這個類的所有屬性和方法

對於任意的一個物件,都能夠呼叫它的任意一個方法和屬性。

11.2、反射提供的功能有:

1)、在執行時判斷任意一個所屬的類

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

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

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

5)、生成動態代理

11.3、獲取反射物件的三種方式

第一種、Class.forName(全類名),推薦使用,可以捕獲異常ClassNotFoundException

package com.cn.fanshe;

public class Test {

   public static void main(String[] args) {

      //獲取反射物件(反射入口)::

      /**

       * 獲取反射物件有

3種方式:

       * 第一種、Class.forName(全類名)

       * 第二種、類名.class

       * 第三種、物件.getClass()

       * */

      try {

         Class<?> userClazz=Class.forName("com.cn.fanshe.User");

         System.out.println(userClazz);

      } catch (ClassNotFoundException e) {

         e.printStackTrace();

      }

   }

}

第二種、類名.class

Class<?> userClazz=User.class;

System.out.println(userClazz);

第三種、物件.getClass()

//1.建立物件

User user=new User();

Class<?> userClazz=user.getClass();

System.out.println(userClazz);

11.4、獲取反射類中的所有公共方法

package com.cn.fanshe;

import java.lang.reflect.Method;

/**

 * 1、獲得所有的公共方法(本類、父類以及介面中的所有方法,符合訪問修飾符的public方法,但不包括private方法)

 * */

public class Test {

   public static void getAllMethod(){

      //1.獲得反射物件

      Class<?> userClazz=null;

      try {

         userClazz=Class.forName("com.cn.fanshe.User");

      } catch (ClassNotFoundException e) {

         e.printStackTrace();

      }

      //2.獲得所有的公共方法

      Method[] methods=userClazz.getMethods();

      //3.遍歷所有的公共方法

      for(Method method:methods){

         System.out.println(method);

      }

   }

   public static void main(String[] args) {

      Test.getAllMethod();

   }

}

11.5、獲得反射類中的所有介面

//1.獲得反射物件

Class<?> userClazz=null;

try {

      userClazz=Class.forName("com.cn.fanshe.User");

} catch (ClassNotFoundException e) {

      e.printStackTrace();

}

Class<?>[] userInterfaces=userClazz.getInterfaces();

for(Class<?> inter:userInterfaces){

   System.out.println(inter);

}

11.6、獲得所有的父類,父類只有1個

Class<?> superClass=userClazz.getSuperclass();

System.out.println(superClass);

11.7、獲得所有的構造方法

Constructor<?>[] constructors=userClazz.getConstructors();

for(Constructor<?> con:constructors){

   System.out.println(con);

}

11.8、獲取所有的公共屬性

Field[] fields=userClazz.getFields();

for(Field fie:fields){

   System.out.println(fie);

}

注:獲取所有公共屬性和方法,則修改為如下:

Field[] fields=userClazz.getDeclaredFields();

11.9、獲取物件的例項,並操作物件

package com.cn.fanshe;

import java.lang.reflect.Field;

/**

 * 1、獲得所有的公共方法(本類、父類以及介面中的所有方法,符合訪問修飾符的public方法,但不包括private方法)

 * */

public class Test {

   public static void test() throws InstantiationException, IllegalAccessException{

      //1.獲得反射物件

      Class<?> userClazz=null;

      try {

         userClazz=Class.forName("com.cn.fanshe.User");

      } catch (ClassNotFoundException e) {

         e.printStackTrace();

      }

      //2.獲取物件例項

      User user=(User) userClazz.newInstance();

      user.setName("Jerry");

      user.setAge(21);

      System.out.println(user.getName()+","+user.getAge());

   }

   public static void main(String[] args) throws InstantiationException, IllegalAccessException {

      Test.test();

   }

}

11.10、建立物件例項並操作物件屬性

//1.獲得反射物件

Class<?> userClazz=null;

try {

      userClazz=Class.forName("com.cn.fanshe.User");

} catch (ClassNotFoundException e) {

      e.printStackTrace();

}

//2.獲取物件例項

User user=(User) userClazz.newInstance();

Field nameField=userClazz.getDeclaredField("name");

nameField.set(user, "張三");

System.out.println(user.getName());

此時會報異常,如下:

Exception in thread "main" java.lang.IllegalAccessException: Class com.cn.fanshe.Test can not access a member of class com.cn.fanshe.User with modifiers "private"

   at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:95)

   at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:261)

   at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:253)

   at java.lang.reflect.Field.doSecurityCheck(Field.java:983)

   at java.lang.reflect.Field.getFieldAccessor(Field.java:927)

   at java.lang.reflect.Field.set(Field.java:680)

   at com.cn.fanshe.Test.test(Test.java:19)

   at com.cn.fanshe.Test.main(Test.java:24)

原因是訪問的是私有的name,需要修改屬性的訪問許可權,如果因為訪問修飾符限制造成的異常,可以通過屬性或方法.setAccessible(true),暫時性的開啟許可權。

如下:

//2.獲取物件例項

      User user=(User) userClazz.newInstance();

      Field nameField=userClazz.getDeclaredField("name");

      nameField.setAccessible(true);

      nameField.set(user, "張三");

      System.out.println(user.getName());

注:方法的操作類似屬性,但是方法的呼叫用invoke()

如下:

//2.獲取物件例項

User user=(User) userClazz.newInstance();

//interfaceMethod2是方法名,null是引數型別

Method method=userClazz.getDeclaredMethod("interfaceMethod2", null);

method.invoke(user, null); //常規方法呼叫如user.say(引數)

11.11、反射的適用場景?

1)、java的反射機制在做基礎框架時十分有用,即反射機制是很多java框架的基石。

最經典的就是在XML檔案或Properties裡面寫好配置,然後在java類裡面解析XML或properties裡面的內容,得到一個字串,然後用反射機制,根據這個字串獲得某個類的Class例項,這樣就可以動態配置一些東西,不用每次都要在程式碼裡面去new或者做其它事情,以後要改的話直接修改配置檔案,程式碼維護起來就方便了。

2)、java類裡面不一定能直接呼叫另外的方法,這時可以通過反射機制來實現。

3)、在編碼階段不知道那個類名,要在執行期從配置檔案讀取類名,這時就沒辦法硬編碼new ClassName();而必須用到反射才能建立這個物件,反射的目的就是為了擴充套件未知的應用。

11.12、反射的效能問題

反射機制是一種程式自我分析的能力,用於獲取一個類的變數、建構函式、方法、修飾符

優點:執行期型別的判斷,動態類載入,動態代理使用反射

缺點:效能是一個問題,反射相當於一系列解釋操作,通知JVM要做的事情,效能比直接的java程式碼要慢很多。

11.13、程式設計師在自己的業務開發中應該儘量遠離反射

反射:在流行的庫如hibernate和spring中,反射自然有其用武之地。不過內省業務程式碼在很多時候都不是一件好事,原因有很多,總之不建議使用反射。

首先是程式碼可讀性和工具支援,開啟IDE,尋找你的java程式碼的內部依賴,很容易吧。

現在使用反射來替換掉你的程式碼然後再試一下,結果如何呢?如果通過反射來修改已經封裝好的物件狀態,那麼結果將會變得更加不可控。

相關推薦

java19---反射機制

java---反射機制 java語言允許通過程式化的方式間接對Class進行操作,Class檔案由類載入器裝載後,在JVM中形成一份描述Class結構的元資訊物件,通過該元資訊物件可以獲知Class的結構資訊:如 建構函式、屬性和方法等。 java允許使用者藉由這個Cl

Java--反射之在執行時使用反射分析物件

對於我這樣一個菜鳥級別的人來說,學習反射真心有點鬱悶,今天繼續分享一下學習心得。在執行時反射分析物件,可以利用反射機制,檢視資料域的實際內容,檢視物件域的關鍵方法是Field類中的get方法,例如f是一個Field型別的物件,(通過getDeclarerFields得到的物件

小白也能看懂的外掛化DroidPlugin原理-- 反射機制和Hook入門

  前言:在上一篇博文《小白也能看懂的外掛化DroidPlugin原理(一)-- 動態代理》中詳細介紹了 DroidPlugin 原理中涉及到的動態代理模式,看完上篇博文後你就會發現原來動態代理真的非常簡單,只不過就是實現一個 InvocationHandler 介面重寫一

Java程式設計師從笨鳥到菜鳥之反射和代理機制

   反射和代理機制是JDK5.0提供的java新特性,反射的出現打破了java一些常規的規則,如,私有變數不可訪問。但反射和代理在學習過程中也是一個比較難理解的知識點。本人曾經學過一段時間的反射和代理,但好長時間不用好像有點生疏了,當時學的時候就理解的不是很透徹,這次總結算是重新學習一遍吧,如果有什麼錯誤,

Java基礎十三反射

構造 調用 div for 性能 使用 判斷 true con 一、反射 1、反射概念   JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱

8.2java學習筆記反射

一、基礎知識   物件是表示或封裝一些資料,一個類被載入後JVM會建立一個對應該類的Class物件,   類的整個結構資訊會被放在對應的物件中,通過這個物件我們可以獲取改類的全部資訊,   而這些操作稱為反射。   二、反射基本操作   2.1獲取物件類   上面說了每一個類在載入時會

java 反射 反射對屬性、方法的操作

package com.reflect; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 反

java 反射 反射中Class常見的方法和屬性

package com.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * 反射中Class常見的方法和屬

Java高階篇——反射

  之前寫到了設計模式的代理模式,因為下一篇動態代理等內容需要用到反射的知識,所以在之前Java篇的基礎上再寫一篇有關反射的內容,還是以實際的程式為主,瞭解反射是做什麼的、應該怎麼用。 一、什麼是反射   反射就是把Java類中的各個成分對映成一個個的Java物件。即在執行狀態中,對於任意一個類,都能夠知道這

Java提高班反射和動態代理JDK Proxy和Cglib

反射和動態代理放有一定的相關性,但單純的說動態代理是由反射機制實現的,其實是不夠全面不準確的,動態代理是一種功能行為,而它的實現方法有很多。要怎麼理解以上這句話,請看下文。 一、反射 反射機制是 Java 語言提供的一種基礎功能,賦予程式在執行時自省(introspect,官方用語)的能力。通過反射我們可

Java內容梳理19API學習7執行緒

目錄: 1、程序和執行緒 2、執行緒的建立 3、執行緒的執行方式和使用場景 4、執行緒的生命週期 5、執行緒優先順序 6、守護執行緒 7、執行緒常用API 8、執行緒安全 9、鎖機制 10、執行緒同步控制(死鎖的介紹) 11、定時器 1、程序和執行

Netflix Eureka原始碼分析19——eureka server叢集機制原始碼剖析:登錄檔同步以及高可用

(1)eureka core的BootStrap裡面,有一塊程式碼,是PeerEurekaNodes的程式碼,其實是在處理eureka server叢集資訊的初始化,會執行PeerEurekaNodes.start()方法 public class EurekaBootSt

JAVA基礎19---陣列的定義、初始化及遍歷

陣列 陣列的定義:將同種型別的資料,有組織的存放與一定的記憶體空間中。 陣列的定義格式:           常用的格式:                                ①資料型別[]  陣列名稱 = new 資料型別[定義陣列的大小];      

HDPCD-Java-複習筆記19

Hive Apache  Hive  maintains metadata information in a metastore to generate tables. A Hive table consists of: ·         A schema stor

Java集合——HashMap擴容機制——resize

HashMap的擴容機制---resize() 雖然在hashmap的原理裡面有這段,但是這個單獨拿出來講rehash或者resize()也是極好的。 什麼時候擴容:當向容器新增元素的時候,會判斷當前容器的元素個數,如果大於等於閾值(知道這個閾字怎麼念嗎?不念fa值

Java基礎反射和Class

一、簡介 Java反射是Java被視為動態語言的一個關鍵性質,這個機制允許程式在執行時透過Reflection APIs取得任何一個已知名稱的class的內部資訊,包括其modifiers(諸如public, static 等)、superclass(例如Object)、實現之interface

java併發——執行緒池執行機制和如何使用

合理利用執行緒池能夠帶來三個好處。 1、第一:降低資源消耗。通過重複利用已建立的執行緒降低執行緒建立和銷燬造成的消耗。 2、第二:提高響應速度。當任務到達時,任務可以不需要的等到執行緒建立就能立即執行。 3、第三:提高執行緒的可管理性。執

Haskell語言學習筆記19File IO

副作用 才會 lose file 類型 ask pen 函數 有效 關於IO Action 類型為IO t。 運算時不執行,因而沒有任何效果,只有執行時才會有效果,產生副作用。 一個IO Action只有在其他IO Action中才能被執行。 類型為IO t的I

ActiveMQ19:Consumer高級特性之獨有消費者Exclusive Consumer

consumer高級特性之獨有消費者(exclusive consumer)一、簡介Queue中的消息是按照順序被分發到consumers的。然而,當你有多個consumers同時從相同的queue中提取消息時,你將失去這個保證。因為這些消息是被多個線程並發的處理。有的時候,保證消息按照順序處理是很重要的。如

Windows Phone開發19:三維透視效果

end 理論知識 form 之間 3d模型 中間 第一個 一個 好的 三維效果也可以叫透視效果,所以,我幹脆叫三維透視效果。理論知識少講,直接用例開場吧,因為這個三維效果其實很簡單,比上一節中的變換更省事,不信?一起來做一做練習吧。 練習一:把對象沿Y軸旋轉45度。 默認情