java 注解反射 项目实战

2年前 (2022) 程序员胖胖胖虎阿
245 0 0

注解反射 项目实战

  • 前言
  • 一、注解声明
  • 二、反射实现
  • 三、功能验证实现
  • 总结

前言

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);

    }
}

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

java 注解反射 项目实战

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

java 注解反射 项目实战

总结

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

版权声明:程序员胖胖胖虎阿 发表于 2022年11月12日 下午3:24。
转载请注明:java 注解反射 项目实战 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...