本文主要介紹反射的一些基本概念,基本方法呼叫,和在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();
  }
}
.