1. 程式人生 > >反射機制在java中的應用

反射機制在java中的應用

 本文主要介紹反射的一些基本概念,基本方法呼叫,和在java中的一些使用,主要是在模式中的使用如 工程模式,動態代理模式,dagger2,Butterknife 等也會用到

反射的基本概念

 獲得class<?>的三種方法
Class<?> cls1 = ReflectionActivity.class;
ReflectionActivity activity = new ReflectionActivity();
Class<?> cls2 = activity.getClass();
try {
    Class<?> cls3 = Class.forName("com.sun.study.ui.activity.ReflectionActivity"
); } catch (ClassNotFoundException e) { e.printStackTrace(); } 基本方法羅列 getName():獲得類的完整名字。 newInstance():通過類的不帶引數的構造方法建立這個類的一個物件。 getFields():獲得類的public型別的屬性。 getDeclaredFields():獲得類的所有屬性。 getMethods():獲得類的public型別的方法。 getDeclaredMethods():獲得類的所有方法。 getMethod(String name, Class[] parameterTypes):獲得類的特定方法。 getModifiers
()和Modifier.toString():獲得屬修飾符,例如privatepublicstaticgetReturnType():獲得方法的返回型別 getParameterTypes():獲得方法的引數型別 getConstructors():獲得類的public型別的構造方法。 getConstructor(Class[] parameterTypes):獲得類的特定構造方法。 getSuperclass():獲取某類的父類 getInterfaces():獲取某類實現的介面 getAnnotation()獲得註解

羅列一個列的所有方法

private void getMethodsInfo() {
    Class<ReflectionActivity> cls
= ReflectionActivity.class; Method[] methods = cls.getDeclaredMethods(); if (methods == null) return; StringBuilder sb = new StringBuilder(); for (Method method:methods) { sb.append(Modifier.toString(method.getModifiers())).append(" "); sb.append(method.getReturnType()).append(" "); sb.append(method.getName()).append("("); Class[] parameters = method.getParameterTypes(); if (parameters != null) { for (int i=0; i<parameters.length; i++) { Class paramCls = parameters[i]; sb.append(paramCls.getSimpleName()); if (i < parameters.length - 1) sb.append(", "); } } sb.append(")\n\n"); } tvInfo.setText(sb.toString()); }

獲得類的屬性,並修改器屬性的值

private void modifyFieldValue() {
    Class<ReflectionActivity> cls = ReflectionActivity.class;
    Field[] fields = cls.getDeclaredFields();
    if (fields == null) return;

    StringBuilder sb = new StringBuilder();
    sb.append("獲得類的所有屬性資訊:\n\n");
    for (Field field:fields) {
        sb.append(Modifier.toString(field.getModifiers())).append(" ");
        sb.append(field.getType().getSimpleName()).append(" ");
        sb.append(field.getName()).append(";");
        sb.append("\n\n");
    }

    try {
        sb.append("屬性i的預設值:i = ");
        Field f = cls.getDeclaredField("i");
        sb.append(f.getInt("i")).append("\n\n");
        f.set("i", 100);
        sb.append("屬性i修改後的值:i = ");
        sb.append(f.getInt("i")).append("\n\n");
    } catch (Exception e) {
        e.printStackTrace();
    }

    tvInfo.setText(sb.toString());
    toolbar.setSubtitle("修改型別Int屬性i的值");
}

註解(Annotation),也叫元資料。一種程式碼級別的說明。它是JDK 1.5及以後版本引入的一個特性,與類、介面、列舉是在同一個層次。它可以宣告在包、類、欄位、方法、區域性變數、方法引數等的前面,用來對這些元素進行說明,註釋。
自定義一個clinckEvent

@Target(ElementType.ANNOTATION_TYPE)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface  clinckEvent  
{  
    Class<?> listener();  

    String listenerMethod();  

    String methodName();  
} 

再接著定義一個

@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
@clinckEvent(listener = View.OnClickListener.class, listenerMethodr = "setOnClickListener", methodName = "onClick")  
public @interface OnClick  
{  
    int[] value();  
}  

程式碼中使用

  class  Activity{
   @OnClick({ R.id.id_btn, R.id.id_btn02 })  
    public void clickBtnInvoked(View view) 
    }

通過反射獲得註解

 Class<? extends Activity> clazz = activity.getClass();  
        Method[] methods = clazz.getMethods();  
        //遍歷所有的方法  
        for (Method method : methods)  
        {  
            Annotation[] annotations = method.getAnnotations();  
            //拿到方法上的所有的註解  
            for (Annotation annotation : annotations)  

        Class<? extends Annotation> annotationType = annotation  
                        .annotationType();  
                //拿到註解上的註解  
                clinckEvent getAnnotation = annotationType  
                        .getAnnotation(clinckEvent.class); 

if (getAnnotation != null)  
                {  
                    //取出設定監聽器的名稱,監聽器的型別,呼叫的方法名  
                    String listenerSetter = getAnnotation  
                            .listenerSetter();  
                    Class<?> listener = getAnnotation.listener();  
                    String methodName = getAnnotation.methodName(); 

}
  //拿到Onclick註解中的value方法  
                        Method aMethod = annotationType  
                                .getDeclaredMethod("value");  
                        //取出所有的viewId  
                        int[] viewIds = (int[]) aMethod  
                                .invoke(annotation, null);




}
/** 
     * 注入主佈局檔案 
     *  
     * @param activity 
     */  
    private static void injectContentView(Activity activity)  
    {  
        Class<? extends Activity> clazz = activity.getClass();  
        // 查詢類上是否存在ContentView註解  
        ContentView contentView = clazz.getAnnotation(ContentView.class);  
        if (contentView != null)// 存在  
        {  
            int contentViewLayoutId = contentView.value();  
            try  
            {  
                Method method = clazz.getMethod(METHOD_SET_CONTENTVIEW,  
                        int.class);  
                method.setAccessible(true);  
                method.invoke(activity, contentViewLayoutId);  
            } catch (Exception e)  
            {  
                e.printStackTrace();  
            }  
        }  
    }  

1**工程模式中使用**

public class ProductFatory<T> {  
    public <T>  T Object getInstance(String className){  
        Object instance=null;  
        try {  
            Class cls=Class.forName(className);  
            instance= cls.newInstance();  
        } catch (ClassNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (InstantiationException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        return instance;  

    }  
  1. 代理模式中使用
    動態代理
    InvocationHandler
    Proxy
public interface Subject   
{   
  public void doSomething();   
}   
public interface  Advice  
{   
  public void exe();   
}  
 public class RealAdvice implements Advice 
{   
  public void exe()   
  {   
      //驗證條件是否滿足 
  }   
}    
public class RealSubject implements Subject   
{   
  public void doSomething()   
  {   
    System.out.println( "call doSomething()" );   
  }   
}   
public class ProxyHandler implements InvocationHandler   
{   
  private Object proxied;   

  public ProxyHandler( Object proxied )   
  {   
    this.proxied = proxied;   
  }   

  public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable   
  {   
    //在轉調具體目標物件之前,可以執行一些功能處理
     Boolean isFlag=“增加自己的判斷邏輯”
       if(isFlag){
        new RealAdvice().exe();
       }
    //轉調具體目標物件的方法
    return method.invoke( proxied, args);  

    //在轉調具體目標物件之後,可以執行一些功能處理
  }    
}

client 程式碼

public class Client  
{   
  public static void main( String args[] )   
  {   
    RealSubject real = new RealSubject();   
    Subject proxySubject = (Subject)Proxy.newProxyInstance(Subject.class.getClassLoader(), 
     new Class[]{Subject.class}, 
     new ProxyHandler(real));

    proxySubject.doSomething();   
  } 

安卓中的BIndler 原理Aidl 通訊

 Router.build(uri).callback(new RouteCallback() { // 新增結果回撥
                @Override
                public void callback(RouteResult state, Uri uri, String message) {
                    if (state == RouteResult.SUCCEED) {
                        Toast.makeText(MainActivity.this, "succeed: " + uri.toString(), Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(MainActivity.this, "error: " + uri + ", " + message, Toast.LENGTH_SHORT).show();
                    }
                }
            }).go(this);

增加了注入模組

結合這邊文章看

會有意想不到的收穫
Activity注入控制元件view 和點選事件

/**
* 我們自己的類
*/
@Module
public class MarkCarModule {

    public MarkCarModule(){ }

    @Provides Engine provideEngine(){
        return new Engine("gear");
    }
}

/**
* Dagger2生成的工廠類
*/
public final class MarkCarModule_ProvideEngineFactory implements Factory<Engine> {
  private final MarkCarModule module;

  public MarkCarModule_ProvideEngineFactory(MarkCarModule module) {
    assert module != null;
    this.module = module;
  }

  @Override
  public Engine get() {
    return Preconditions.checkNotNull(
        module.provideEngine(), "Cannot return null from a [email protected] @Provides method");
  }

  public static Factory<Engine> create(MarkCarModule module) {
    return new MarkCarModule_ProvideEngineFactory(module);
  }

  /** Proxies {@link MarkCarModule#provideEngine()}. */
  public static Engine proxyProvideEngine(MarkCarModule instance) {
    return instance.provideEngine();
  }
}
/**
* 我們自己的類
*/
@Component(modules = {MarkCarModule.class})
public interface CarComponent {

    void inject(Car car);
}

用到了建造者模式
/**
* Dagger2生成的CarComponent實現類
*/
public final class DaggerCarComponent implements CarComponent {
  private Provider<Engine> provideEngineProvider;

  private MembersInjector<Car> carMembersInjector;

  private DaggerCarComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {
    return new Builder();
  }

  public static CarComponent create() {
    return builder().build();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {

    this.provideEngineProvider = MarkCarModule_ProvideEngineFactory.create(builder.markCarModule);

    this.carMembersInjector = Car_MembersInjector.create(provideEngineProvider);
  }

  @Override
  public void inject(Car car) {
    carMembersInjector.injectMembers(car);
  }

  public static final class Builder {
    private MarkCarModule markCarModule;

    private Builder() {}

    public CarComponent build() {
      if (markCarModule == null) {
        this.markCarModule = new MarkCarModule();
      }
      return new DaggerCarComponent(this);
    }

    public Builder markCarModule(MarkCarModule markCarModule) {
      this.markCarModule = Preconditions.checkNotNull(markCarModule);
      return this;
    }
  }
}
ublic final class Car_MembersInjector implements MembersInjector<Car> {
  private final Provider<Engine> engineProvider;

  public Car_MembersInjector(Provider<Engine> engineProvider) {
    assert engineProvider != null;
    this.engineProvider = engineProvider;
  }

  public static MembersInjector<Car> create(Provider<Engine> engineProvider) {
    return new Car_MembersInjector(engineProvider);
  }

  @Override
  public void injectMembers(Car instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.engine = engineProvider.get();
  }

  public static void injectEngine(Car instance, Provider<Engine> engineProvider) {
    instance.engine = engineProvider.get();
  }
}

相關推薦

Java反射機制的簡單應用

mod arc pos ret system containe java反射機制 track san 一直感覺java的反射機制非常強大,可是可用的地方不多。在android學習的時候。一直想實現掛斷電話的功能,可是

Java反射機制的深入應用

前言 在上一篇文章中介紹了Java反射的基本概念以及基本應用,不熟悉的朋友可以點這裡 本篇文章將重點介紹反射機制的深入應用 反射除了可以取得一個類的完整結構外,還可以呼叫類中的指定方法或指定屬性,並且可以通過反射完成對陣列的操作。 通

java反射機制的業務應用場景-1

       好久不寫東西,最近整理之前的東西時發現以前有一些寫好的東西,其實都是一些學習筆記或是對某個技術理解的一些感想,覺得很有意思,拿出來和大家分享一下。        這篇文章我們先來說一下java的反射機制,java的反射機制其實在1.2的時候就已經有了,那時我們

快取機制:java快取的原理

外存:   也就是我們經常說的(CDEF盤的大小)外儲存器是指除計算機記憶體及CPU快取以外的儲存器,此類儲存器一般斷電後仍然能儲存資料。常見的外儲存器有硬碟、軟盤、光碟、U盤等,一般的軟體都是安裝在外存中 記憶體:   記憶體是計算機中重要的部件之一,它是與CPU進行

Java反射之——JavaClass類的使用

Java語言中,萬事萬物皆物件,但是靜態成員、基本的資料型別(基本的資料型別也有自己的包裝類)等並不是物件,因為靜態的變數和函式屬於類,我們可以通過 類.靜態變數 / 類.靜態函式等方式呼叫。 public class Test {     private st

Java應用工廠(Factory)模式

基本概念 Factory Method是一種建立性模式,它定義了一個建立物件的介面,但是卻讓子類來決定具體例項化哪一個類.當一個類無法預料要建立哪種類的物件或是一個類需要 由子類來指定建立的物件時我們就需要用到Factory Method 模式了.簡單說來,Factory M

Java應用檔案鎖

檔案鎖在作業系統中是很平常的事情,當多個執行的程式需要併發修改同一個檔案時,程式之間需要某種機制來進行通訊,使用檔案鎖可以有效的阻止多個程序併發修改同一個檔案,所以現在的大部分作業系統都提供了檔案鎖的功能。     從JDK1.4的NIO開始,Java開始提

art的monitor機制--java Synchronized與art Monitor的關係

在java 世界中我們使用synchronized 關鍵字對需要做同步的程式碼進行上鎖操作,來保證同一時刻只有一個執行緒可以對加鎖程式碼段進行同步操作.synchronized機制實現依賴對應虛擬機器的實現,在android中實現該功能的就是art的Monitor部分. 1

Java反射機制在工廠模式應用

在本篇文章中就不詳細介紹工廠模式,主要介紹一下反射在工廠模式中的使用,讓讀者對反射機制帶來的好處有更深的認識。 首先看一下簡單工廠模式 簡單工廠模式(simple factory)是類的建立模式,又叫靜態工廠方法(static factory method)模式。 簡單工廠

反射機制java應用

本文主要介紹反射的一些基本概念,基本方法呼叫,和在java中的一些使用,主要是在模式中的使用如 工程模式,動態代理模式,dagger2,Butterknife 等也會用到 反射的基本概念 獲得class<?>的三種方法 Class<

Java反射機制

導致 buffer 自己 net -- 實例 reflect .config lang 學習Java的同學註意了!!! 學習過程中遇到什麽問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:618528494 我們一起學Java!

Java反射機制(一)

erl void port 令行 sage [0 ray 輸出 我們 基本概念   在Java運行時環境中,對於任意一個類,能否知道這個類有哪些屬性和方法?對於任意一個對象,能否調用它的任意一個方法?   答案是肯定的。   這種動態獲取類的信息以及動態調用對象的方法的功能

Java反射機制demo(五)—獲得並調用一個類的方法

color 擁有 oca logs over super getmethod equals() bool 這個demo在使用反射機制操作屬性之前,主要原因是因為在.class文件字節碼中,方法排在屬性的前面。 1,獲得一個類中的方法 先看一下方法和運行結果。獲取所有的方

JAVA反射機制五(JavaBean的內省與BeanUtils庫)

getc ron 輸出結果 下載 比較 static 完成 自動完成 規則   內省(Introspector) 是Java 語言對JavaBean類屬性、事件的一種缺省處理方法。   JavaBean是一種特殊的類,主要用於傳遞數據信息,這種類中的方法主要用於訪問私有的

JAVA反射機制六(java.lang.reflect包)

instance 檢查 item 類繼承 final win 基類 cte member 一、簡介 java.lang.reflect包提供了用於獲取類和對象的反射信息的類和接口。反射API允許對程序訪問有關加載類的字段,方法和構造函數的信息進行編程訪問。它允許在安全限制

Java反射機制詳解

turn face instance java struct () 分享 2.6 一個     序言       在學習java基礎時,由於學的不紮實,講的實用性不強,就覺得沒用,很多重要的知識就那樣一筆帶過了,像這個馬上要講的反射機制一樣,當時學的時候就忽略了,到後來學習

Java反射機制能夠獲取的信息,與應用

rri 代理 pan [] reflect 語言 子類 list tro 一、什麽是Java反射機制? 【1】反射機制是在運行狀態中,對於任何一個類,都能夠知道這個類的所有屬性和方法; 【2】對於任意一個對象,都能夠調用它的任意一個屬性和方法; 像這種動態獲取類的信

Java入門提高篇】Day13 Java反射機制

== getchar 復制對象 enc 類型判斷 amt sim 博客 contains   前一段時間一直忙,所以沒什麽時間寫博客,拖了這麽久,也該更新更新了。最近看到各種知識付費的推出,感覺是好事,也是壞事,好事是對知識沈澱的認可與推動,壞事是感覺很多人忙於把自己的知識

java反射機制應用之動態代理

代理類 過多 size bject interface 並且 編譯期 代理 抽象 1.靜態代理類和動態代理類區別 靜態代理:要求被代理類和代理類同時實現相應的一套接口;通過代理類的對象調用重寫接口的方法時,實際上執行的是被代理類的同樣的 方法的調用。 動態代理:在程序運

java反射機制——獲取位元組碼對應類的函式

package cn.itcast.reflect.demo; import java.lang.reflect.Constructor; import java.lang.reflect.Method; //獲取類中的函式 public class ReflectDemo4 { public