反射机制在java中的应用

本文详细介绍了Java反射的基础概念及方法调用,并展示了其在多种设计模式中的运用,包括工程模式、动态代理模式等。此外,还深入探讨了反射在流行框架如Dagger2和Butterknife中的实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 本文主要介绍反射的一些基本概念,基本方法调用,和在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 通信

一个不错的框架
https://github.com/chenenyu/Router
各业务模块之间不允许存在相互依赖关系,它们之间的跳转通讯采用路由框架 Router 来实现

 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 和点击事件

http://blog.youkuaiyun.com/lmj623565791/article/details/39269193

4. dagger2
module inject component
推荐一篇不错的入门文章
http://www.open-open.com/lib/view/open1482201981550.html
源码学习

/**
* 我们自己的类
*/
@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 non-@Nullable @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();
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值