java 注解反射 项目实战


前言

在这里插入图片描述

实战需求通过自定义注解与反射实现页面跳转的参数注入:

  1. 页面跳转携带参数
  2. 使用注解标记属性参数
  3. 通过反射读取打印数据

一、注解声明

注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

在文章开始之前,我们先来写一个注解接口:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
    String value() default "";
}

@Target注解标记另一个注解,以限制可以应用注解的Java 元素类型,Target 总共有八个元素类型。@Retention注解指定标记注解的存储方式有三种类型,有兴趣的可以看我另一篇文章java 中的反射注解,进行学习了解,这里我就不再赘述了。

  • @Target(ElementType.FIELD): 允许在类与类属性上标记该注解。
  • @Retention(RetentionPolicy.RUNTIME):标记的注解由JVM保留,因此运行时环境可以使用它。

二、反射实现

在贴源码之前,我们先来看一下接下来我们需要使用到的一些方法:

  • getClass(): 获取当前上下文中的所有类。
  • getIntent():获取当前上下文中的所有数据。
  • getDeclaredFields():获取当前class 中的所有成员变量。
  • getAnnotation():获取当前上下文中的注解。
  • extras.get(key):获取当前 key 传入的数据。

接下我们直接创建一个反射 InjectUtils 工具类:

public class InjectUtils {

    public static void InjectAutowired(Activity activity) {

//       获取当前所有的类
        Class<? extends Activity> aClass = activity.getClass();
//       获取数据
        Intent intent = activity.getIntent();
        Bundle extras = intent.getExtras();
        if (extras == null) {
            return;
        }

//       获取此类的所有成员
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.isAnnotationPresent(Autowired.class)) {
                Autowired autowired = field.getAnnotation(Autowired.class);
//               获取当前key
                String key = TextUtils.isEmpty(autowired.value()) ? field.getName() : autowired.value();
                if (extras.containsKey(key)) {
                    Object obj = extras.get(key);
//                  获取单个数组元素
                    Class<?> componentType = field.getType().getComponentType();
//                  当前属性是数组并且是 Parcelable(子类)数组
                    if (field.getType().isArray() && Parcelable.class.isAssignableFrom(componentType)) {
                        Object[] objs = (Object[]) obj;
//                      创建对应类型的数组,objs 拷贝
                        Object[] objects = Arrays.copyOf(objs, objs.length, (Class<? extends Object[]>) field.getType());
                        obj = objects;
                    }
//                  开启读写权限
                    field.setAccessible(true);
                    try {
                        field.set(activity, obj);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

}

文章代码并不多,结合我上面的注释及上面的一些主要方法的讲解,应该非常容易懂的哦。

三、功能验证实现

首先我们先创建一个 Activity 并实现数据的传参及跳转功能:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onClick(View view) {

        Intent intent = new Intent(this, MainActivity2.class);
        intent.putExtra("name", "tiger");

        startActivity(intent);
    }
}

在 Activity2 中调用反射工具类,并通过注解的方式,打印输出属性变量:

public class MainActivity2 extends AppCompatActivity {

    @Autowired
    String name;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        InjectUtils.InjectAutowired(this);
        System.out.println(name);

    }
}

到这里,本篇文章就已经结束了,接下来我们来运行查看一下结果:

image-20220816140418503

点击模拟器中的按钮,进去界面跳转,内容输入如下:

image-20220816140452070

总结

本篇文章,使用自定义注解实战的方式,为大家带来更直观的学习理解,或许没有那么多的文字,但是我将详细的讲解实战示例中注解、反射中的使用说明,看到这里,我想你也应该学会了,感谢你的支持。

  • 34
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半身风雪

感谢打赏,你的鼓励,是我创作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值