1. 程式人生 > >android 反射機制和反射呼叫方法

android 反射機制和反射呼叫方法

對於android 中很多類沒有開放出來,考慮到這些API不穩定,後續有可能會更改,所有沒有在SDK中暴露出來給使用者使用。但是我們在開放的過程中還是需要使用到一些android 系統中未開放出來的class,這時候我們就可以通過反射機制來呼叫。

JAVA程式碼中  @hide 標識的class或者是method都是沒有編到SDK中的,也就是我們說的隱藏介面。

如果通過反射機制呼叫隱藏介面:
比如說下面的程式碼就可以獲取到隱藏類StatusBarManager
Class  statusBarManager = Class.forName("android.app.StatusBarManager");

通過getMethod來獲取到隱藏類的方法
expand = statusBarManager.getMethod("expandNotificationsPanel");


通過invoke來執行該函式

expand.invoke();

以下轉自:http://blog.csdn.net/ff313976/article/details/7931491

JAVA反射機制

JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。
Java反射機制主要提供了以下功能: 在執行時判斷任意一個物件所屬的類;在執行時構造任意一個類的物件;在執行時判斷任意一個類所具有的成員變數和方法;在執行時呼叫任意一個物件的方法;生成動態代理。
1. 得到某個物件的屬性

public
 Object getProperty(Object owner, String fieldName) throws Exception {   

     Class ownerClass = owner.getClass();   

     Field field = ownerClass.getField(fieldName);   

     Object property = field.get(owner);   

     return property;   

}  

public Object getProperty(Object owner, String fieldName) throws
 Exception {   

     Class ownerClass = owner.getClass();   

     Field field = ownerClass.getField(fieldName);   

     Object property = field.get(owner);   

     return property;   

}  

  1. public Object getProperty(Object owner, String fieldName) throws Exception {  
  2.      Class ownerClass = owner.getClass();  
  3.      Field field = ownerClass.getField(fieldName);  
  4.      Object property = field.get(owner);  
  5.      return property;  
  6. }  

 
Class ownerClass = owner.getClass():得到該物件的Class。

Field field = ownerClass.getField(fieldName):通過Class得到類宣告的屬性。

Object property = field.get(owner):通過物件得到該屬性的例項,如果這個屬性是非公有的,這裡會報IllegalAccessException。

2. 得到某個類的靜態屬性

public Object getStaticProperty(String className, String fieldName)   

             throws Exception {   

     Class ownerClass = Class.forName(className);   

     Field field = ownerClass.getField(fieldName);   

     Object property = field.get(ownerClass);   

     return property;   

}  

public Object getStaticProperty(String className, String fieldName)   

             throws Exception {   

     Class ownerClass = Class.forName(className);   

     Field field = ownerClass.getField(fieldName);   

     Object property = field.get(ownerClass);   

     return property;   

}  

  1. public Object getStaticProperty(String className, String fieldName)  
  2.              throws Exception {  
  3.      Class ownerClass = Class.forName(className);  
  4.      Field field = ownerClass.getField(fieldName);  
  5.      Object property = field.get(ownerClass);  
  6.      return property;  
  7. }  

 

Class ownerClass = Class.forName(className) :首先得到這個類的Class。

Field field = ownerClass.getField(fieldName):和上面一樣,通過Class得到類宣告的屬性。

Object property = field.get(ownerClass) :這裡和上面有些不同,因為該屬性是靜態的,所以直接從類的Class裡取。

3. 執行某物件的方法

public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {   

     Class ownerClass = owner.getClass();   

     Class[] argsClass = new Class[args.length];   

     for (int i = 0, j = args.length; i < j; i++) {   

         argsClass[i] = args[i].getClass();   

     }   

      Method method = ownerClass.getMethod(methodName,argsClass);   

     return method.invoke(owner, args);   

}  

public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {       

     Class ownerClass = owner.getClass();   

     Class[] argsClass = new Class[args.length];   

     for (int i = 0, j = args.length; i < j; i++) {   

         argsClass[i] = args[i].getClass();   

     }   

      Method method = ownerClass.getMethod(methodName,argsClass);   

     return method.invoke(owner, args);   

}  

  1. public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {  
  2.      Class ownerClass = owner.getClass();  
  3.      Class[] argsClass = new Class[args.length];  
  4.      for (int i = 0, j = args.length; i < j; i++) {  
  5.          argsClass[i] = args[i].getClass();  
  6.      }  
  7.       Method method = ownerClass.getMethod(methodName,argsClass);  
  8.      return method.invoke(owner, args);  
  9. }  

 
Class owner_class = owner.getClass() :首先還是必須得到這個物件的Class。

5~9行:配置引數的Class陣列,作為尋找Method的條件。

Method method = ownerClass.getMethod(methodName, argsClass):通過methodName和引數的argsClass(方法中的引數型別集合)陣列得到要執行的Method。

method.invoke(owner, args):執行該Method.invoke方法的引數是執行這個方法的物件owner,和引數陣列args,可以這麼理解:owner物件中帶有引數args的method方法。返回值是Object,也既是該方法的返回值。

4. 執行某個類的靜態方法

public Object invokeStaticMethod(String className, String methodName,   

             Object[] args) throws Exception {   

     Class ownerClass = Class.forName(className);   

     Class[] argsClass = new Class[args.length];   

     for (int i = 0, j = args.length; i < j; i++) {   

         argsClass[i] = args[i].getClass();   

     }   

    Method method = ownerClass.getMethod(methodName,argsClass);   

     return method.invoke(null, args);   

 }  

public Object invokeStaticMethod(String className, String methodName,   

             Object[] args) throws Exception {   

     Class ownerClass = Class.forName(className);   

     Class[] argsClass = new Class[args.length];   

     for (int i = 0, j = args.length; i < j; i++) {   

         argsClass[i] = args[i].getClass();   

     }   

    Method method = ownerClass.getMethod(methodName,argsClass);   

     return method.invoke(null, args);   

 }  

  1. public Object invokeStaticMethod(String className, String methodName,  
  2.              Object[] args) throws Exception {  
  3.      Class ownerClass = Class.forName(className);  
  4.      Class[] argsClass = new Class[args.length];  
  5.      for (int i = 0, j = args.length; i < j; i++) {  
  6.          argsClass[i] = args[i].getClass();  
  7.      }  
  8.     Method method = ownerClass.getMethod(methodName,argsClass);  
  9.      return method.invoke(null, args);  
  10.  }  

 

基本的原理和例項3相同,不同點是最後一行,invoke的一個引數是null,因為這是靜態方法,不需要藉助例項執行。

5. 新建例項

public Object newInstance(String className, Object[] args) throws Exception {   

     Class newoneClass = Class.forName(className);   

     Class[] argsClass = new Class[args.length];   

     for (int i = 0, j = args.length; i < j; i++) {   

         argsClass[i] = args[i].getClass();   

     }   

     Constructor cons = newoneClass.getConstructor(argsClass);   

     return cons.newInstance(args);   

}  

public Object newInstance(String className, Object[] args) throws Exception {   

     Class newoneClass = Class.forName(className);    

     Class[] argsClass = new Class[args.length];   

     for (int i = 0, j = args.length; i < j; i++) {   

         argsClass[i] = args[i].getClass();   

     }   

     Constructor cons = newoneClass.getConstructor(argsClass);   

    return cons.newInstance(args);   

}  

  1. public Object newInstance(String className, Object[] args) throws Exception {  
  2.      Class newoneClass = Class.forName(className);  
  3.      Class[] argsClass = new Class[args.length];  
  4.      for (int i = 0, j = args.length; i < j; i++) {  
  5.          argsClass[i] = args[i].getClass();  
  6.      }  
  7.      Constructor cons = newoneClass.getConstructor(argsClass);  
  8.      return cons.newInstance(args);  
  9. }  

 
這裡說的方法是執行帶引數的建構函式來新建例項的方法。如果不需要引數,可以直接使用newoneClass.newInstance()來實現。

Class newoneClass = Class.forName(className):第一步,得到要構造的例項的Class。

第5~第9行:得到引數的Class陣列。

Constructor cons = newoneClass.getConstructor(argsClass):得到構造子。

cons.newInstance(args):新建例項。

6. 判斷是否為某個類的例項

public boolean isInstance(Object obj, Class cls) {   

     return cls.isInstance(obj);   

}  

public boolean isInstance(Object obj, Class cls) {   

 return cls.isInstance(obj);   

}  

  1. publicboolean isInstance(Object obj, Class cls) {  
  2.      return cls.isInstance(obj);  
  3. }  

 
7. 得到陣列中的某個元素

public Object getByArray(Object array, int index) {   

     return Array.get(array,index);   

}  


相關推薦

android 反射機制反射呼叫方法

對於android 中很多類沒有開放出來,考慮到這些API不穩定,後續有可能會更改,所有沒有在SDK中暴露出來給使用者使用。但是我們在開放的過程中還是需要使用到一些android 系統中未開放出來的class,這時候我們就可以通過反射機制來呼叫。 JAVA程式碼中  @hi

利用Objective-C的反射機制執行時特性實現類靜態方法的動態訪問(一)

如題,灑家今天在搭建蘋果手機APP開發框架中遇到一個坑爹問題,折騰了半天,總算研究出來了,特記錄如下: 1、先說具體需求,本人實現了一個自定義檢視控制元件,通過KVC特性先從plist配置檔案中讀取資料,轉換成模型物件,然後根據模型物件動態建立檢視物件,這時就需要用到Obj

利用Objective-C的反射機制執行時特性實現類靜態方法的動態訪問(二)

繼上次的研究成果繼續深入研究,灑家又完善了下在執行時動態呼叫所有OC類方法的公用方法: typedef void*(*ObjcMsgSend)(id, SEL, ...); - (void *)invoke:(id)inst method:(NSString *)nam

通過Java反射機制獲取物件、方法成員變數

先定義一個JavaBean package com.jim.test.Test; public class User { private int id; private String name = "abc"; private Str

類的加載機制反射——五、使用反射生成JDK動態代理

復用 他也 new mil ont throwable logs object load 使用反射生成JDK動態代理 1.使用Proxy和InvocationHandler創建動態代理 (1)Proxy提供了用於創建動態代理類和動態代理對象的靜態方法,他也是所有動態代理類的

java 類加載機制反射機制

lis 多線程 ati 加鎖 margin 對數 父類 p s list 1.類的加載機制jvm把class文件加載到內存,並對數據進行校驗、解析和初始化,最終形成jvm可以直接使用的java類型的過程。(1)加載 將class文件字節碼內容加載到內存中,並

java反射機制Class類

面向物件思想 一切皆物件 類也是物件,Class類的物件,java.lang.Class Class類的構造器是私有的,只有虛擬機器可以直接建立它的物件, 有三種建立方式:類.class、類物件.getClass、Class.forName 靜態載入:new,發生在編譯的時候 動態載

Java的反射機制使用

文章目錄 一、定義 二、功能 三、反射的實現方式 四、實現反射的類 五、Java動態載入類使用場景 六、反射機制的優缺點? 七、下面不是概念,乾貨來啦!

通過反射機制建立一個構造方法中引數數量可變的物件

自學的時候剛看到Class類與Java反射,才開始講解了Class類得到對應類構造方法的方法。 我們可以用getConstructors()等四個方法得到需要的Constructor構造方法或者其陣列,然後再利用Constructor的newInstance方法進行建立物件

SparkSQL的反射機制自定義建立DataFrame

反射機制 1.RDD[Person]-----(case:反射機制)------>DataFrameF[ROW]---->DataSet[Person]   RDD DF DS     Person ["name","age","address"] {Person:("name","age","

Java 反射機制動態代理是基於什麼原理,瞭解過嗎?

工作多年以及在面試中,我經常能體會到,有些面試者確實是認真努力工作,但坦白說表現出的能力水平卻不足以通過面試,通常是兩方面原因: 1、“知其然不知其所以然”。 做了多年技術,開發了很多業務應用,但似乎並未思考過種種技術選擇背後的邏輯。坦白說,我並不放心把具有一定深度的任務交給他。 2、

JAVA 反射機制,invoke呼叫用法一個小的用法

JAVA反射機制基礎: 參考:http://lavasoft.blog.51cto.com/62575/43218/ http://java.ccidnet.com/art/3539/20070924/1222147_1.htmlJAVA invoke的呼叫: 有如下的類

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

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

Java中反射機制Class.forName、例項物件.class(屬性)、例項物件getClass()的區別

二、Class.forName、例項物件.class(屬性)、例項物件getClass()的區別 1、相同點: 通過這幾種方式,得到的都是Java.lang.Class物件(這個是上面講到的 類在載入時獲得的最終產物) 例如: package demo;public class A{ public st

對於JAVA反射機制CLASS類的個人理解

上週上課老師點我起來回答問題,問了一下JAVA反射機制,我本來對JAVA用得不多,加上有一段時間沒有看過了,所以並沒有能夠答出來,之後就想要好好理解理解,加上老師佈置作業讓弄懂JAVA反射和Class類,所以CSDN第一次寫部落格,就來寫寫我對反射和Class的學習之後的感

Java的反射機制作用

轉自這裡 Java的反射機制是Java特性之一,反射機制是構建框架技術的基礎所在。靈活掌握Java反射機制,對大家以後學習框架技術有很大的幫助。 那麼什麼是Java的反射呢?        大家都知道,要讓Java程式能夠執行,那麼就得讓Java類要被Java虛擬機

Google protocol buffer 的反射機制應用

何謂反射? 我在工作中大量使用了 google protocal buffer, 為了方便描述, 下文簡稱為 pb. pb 的作用和基本使用方法在這裡就不再陳述, 相關的文章網上很多.  這裡主要介紹 pb 的反射機制. 什麼是反射機制呢? 該機制能在執行時, 對於任

反射機制:類中方法及成員變數賦值

Person.java:   package test;   publicclass Person {       private String name;       privateint ag

C#反射解析資料內容,呼叫方法

反射獲取成員值 這部分主要是為了拿到例項的時候我們可能不清楚例項或成員的型別,但知道起成員的名稱或需要拿到其全部成員資訊,這個時候就值得用到反射來獲取類的詳細資訊了。 下面顯示用反射來獲取一個物件某個成員的值。 using System; using

Java中的反射機制動態代理

一、反射概述   反射機制指的是Java在執行時候有一種自觀的能力,能夠了解自身的情況為下一步做準備,其想表達的意思就是:在執行狀態中,對於任意一個類,都能夠獲取到這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性(包括私有的方法和屬性),這種動態獲取的資訊以及動態呼叫物件的方法的功