实现基于注解(Annotation)的数据库框架(四)注解(Annotation)和反射的结合使用

前言#

反射和注解的基本知识我们都已经了解了,这一篇来具体看看他俩如何结合使用,离我们的最终目标越来越近了。

正文#

现在来写一个通过注解来实现setContentView()的功能的Demo。

首先我们需要自定义一个注解,我们命名为ContentView:

package com.lzp.annotationstudy;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by li.zhipeng on 2017/3/9.
 *
 *      注解测试类
 */

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    int value();
}

ContentView注解用来注解某一个类(TYPE),在运行时可以通过反射获取到具体的信息。value()之前介绍过,如果注解只有一个属性,系统推荐用value,注解中的值会以键值对的形式保存,就是属性的名称对应自身的值,而系统默认是value就是其中的一个键,这样的好处之后会看到。

定义好注解,现在就要通过反射来实现具体的功能了:

package com.lzp.annotationstudy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by li.zhipeng on 2017/3/9.
 *
 *      注解工具类
 */

public class AnnotationUtils {

    public static void injectObject(Object handler){
        
        // 拿到参数的Class类型
        Class<?> handleType = handler.getClass();
        // 获取Class类型上的ContentView注解
        ContentView contentView = handleType.getAnnotation(ContentView.class);
        if (contentView != null){
            try {
                // 通过反射找到Class类型中的setContentView(int param)方法
                Method setContentViewMethod = handleType.getMethod("setContentView", int.class);
                // 调用setContentView(int param),第一个是操作的对象,第二个是方法的参数
                setContentViewMethod.invoke(handler, contentView.value());
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}

代码中已经有很详细的注释了,接下来看看MainActivity中的代码:

package com.lzp.annotationstudy;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

//@ContentView(value = R.layout.activity_main)
@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AnnotationUtils.injectObject(this);
    }

}

这里看到了推荐使用value的好处,因为名称默认是value,所以我们就不需要写“value = ”了,如果是其他的名称,例如name之类的,就必须要写了。

看一下运行效果:

这里写图片描述

ok!!!

总结#

到这里所有的基础部分就都已经结束了,demo中反射了类的方法, 反射属性也大同小异,没什么太大的差别,下一篇直奔主题:自定义屌爆了的数据库框架。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容