android 注解和反射 (入门以及使用)

2023-05-16

先来看一看今天的效果:

代码效果:


效果不重要,重要的是代码:

注解

官方解释:

从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。

百度百科

定义一个注解:

public @interface SZJ{
}

元注解:

元注解是用来标示当前注解是干什么用的,什么时候用,常用的有2个

@Target

  • ElementType.ANNOTATION_TYPE 应用于注解类型。
  • ElementType.CONSTRUCTOR 应用于构造函数。
  • ElementType.FIELD 应用于字段或属性。
  • ElementType.LOCAL_VARIABLE 应用于局部变量。
  • ElementType.METHOD 应用于方法级注解。
  • ElementType.PACKAGE 可以应用于包声明。
  • ElementType.PARAMETER 可以应用于方法的参数。
  • ElementType.TYPE 可以应用于类的任何元素。

@Retention

  • RetentionPolicy.SOURCE 仅用于源码级别,会被编译器忽略[编译成class后,会被class丢弃该注解]
  • RetentionPolicy.CLASS 在编译器由编译器保留,JVM会忽略
  • RetentionPolicy.RUNTIME 由JVM保留,运行时可以使用

CLASS包含了SOURCE,RUNTIME包含SOURCE、CLASS。

SOURCE<CLASS<RUNTIME

举例:
在这里插入图片描述
@Retention注解解释:

RetentionPolicy.SOURCE 仅用于源码级别,会被编译器忽略[编译成class后,会被class丢弃该注解]

在这里插入图片描述
这个注解太偏源码,用到的地方比较少

RetentionPolicy.CLASS 在编译器由编译器保留,JVM会忽略

在这里插入图片描述
这个注解一般是APT技术用到的比较多,像一些ARouter,EventBus,Butterknifer等等框架都是用的这个注解.

反射

定义:

反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和
方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。是Java被视为动态语言的关键。

百度百科

使用场景:

不知道某个类是什么类,用来干什么的,就可以通过反射机制直接调用到他内部的属性,以及方法

反射与Class:

反射始于Class,Class是一个类,封装了当前对象所对应的类的信息。一个类中有属性,方法,构造器等,比如说有一个Person类,一个Book类,这些都是不同的类,现在需要一个类,用来描述类,这就是Class,它应该有类名,属性,方法,构造器等。Class是用来描述类的类。

获得Class对象:

  • 类名获取: 类名.class
  • 对象名获取: 对象名.getClass()
  • 全类名获取: Class.forName(“全类名”)

代码展示:

public void test() {
        System.out.println("我是方法哦");

        //类名获取
        Class<?> intCls = int.class;
        Class<?> strCls = String.class;

          //对象名获取
        UserBean userBean = new UserBean();
        Class<? extends UserBean> userBeanCls = userBean.getClass();

        //全类名获取
        try {
            Class<?> userBeanCls2 = Class.forName("com.example.annotation.bean.UserBean");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

反射的🌰:

 public void test() {
        System.out.println("我是方法哦");

        //TODO 对象名获取 class
        UserBean userBean = new UserBean();
        Log.i("szjUserBean",userBean.toString());
        try {
            Class<? extends UserBean> userBeanCls = userBean.getClass();
            Field nameField = userBeanCls.getDeclaredField("name");
            //允许访问 private
            nameField.setAccessible(true);
            //修改状态
            nameField.set(userBean,"SZJ");
            Log.i("szjUserBean",userBean.toString());


            //TODO 全类名获取 class
            Class<?> userBeanCls2 = Class.forName("com.example.annotation.bean.UserBean");
            Field nameField2 = userBeanCls2.getDeclaredField("name");
            nameField2.setAccessible(true);
            //修改状态
            nameField2.set(userBean,"我是SZJ");
            Log.i("szjUserBean",userBean.toString());


            //TODO 反射调用方法
            Method test = userBeanCls.getMethod("test",String.class,int.class);
            String userTestRt = (String) test.invoke(userBean, "张三1", 22);
            Log.i("szjUserBean",userTestRt);


            Method test2 = userBeanCls.getDeclaredMethod("test2",String.class,int.class);
            //允许访问private
            test2.setAccessible(true);
            String userTestRt2 = (String) test2.invoke(userBean, "张三2", 33);
            Log.i("szjUserBean2",userTestRt2);

        } catch (Exception e) {
            e.printStackTrace();
            Log.i("szjError", e.toString());
        }
    }

效果图:

在这里插入图片描述

  • getDeclaredField(String) 获得自己的成员属性[不包括父类,包括private]
  • getFields(String) 获得自己+父类的成员属性[不包括private]
  • Field[] = getDeclaredFields() 获取到所有的属性
  • getMethod(参数名,参数.class) 获得方法[不包括父类,包括private]
  • getDeclaredMethod(参数名,参数.class) 获得自己+父类的成员方法[不包括private]
  • Method[] = getDeclaredMethods() 获取所有的方法
  • Field.setAccessible(boolean) 是否允许访问private属性

反射获取到注解:

  • Field.isAnnotationPresent(Class) 属性上是否有该注解
  • Field.getAnnotation(Class) 获取到属性上注解
  • Annotation[] = Method.getAnnotations() 获取到方法上的所有注解
  • Annotation.annotationType() 获取到方法上注解的注解类型

注解配合反射实现效果

定义注解:

//运行时存在
@Retention(RetentionPolicy.RUNTIME)
//作用来属性上
@Target(ElementType.FIELD)
public @interface szjFind {

   //IdRes: 用来区分传入 int 类型 是否是id
   @IdRes int value();
}

通过反射和注解给控件赋值:

//TODO findViewById
    public void initFind(Activity activity) {
        //获取 Class
        Class<? extends Activity> cls = activity.getClass();

        //getFields 获得自己+父类的成员 不包括 private
        //getDeclaredFields 获得自己的成员(不包括父类,包括 private)

        //获得此类所有的属性
        Field[] fields = cls.getDeclaredFields();
        //遍历这个类中的所有属性
        for (Field field : fields) {
            //判断属性是否被 szjFind 注解
            if (field.isAnnotationPresent(szjFind.class)) {
                //获得注解的实例
                szjFind szjFind = field.getAnnotation(szjFind.class);

                assert szjFind != null;
                //获取 id
                int id = szjFind.value();
                //找到 Id
                View view = activity.findViewById(id);

                //允许操作 private 属性
                field.setAccessible(true);

                try {
                    //反射设置属性的值
                    field.set(activity, view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

在Activity中注册:

szjAnnotationUtil.getInstance().initFind(this);

代码总览图:

因为高度重复,其余代码请下载demo观看

注意:在实际开发项目中不建议采用这种方式,因为反射非常耗时,本篇只是以[获取控件ID/onClick/Intent]他来举例!

完整代码

原创不易,您的点赞就是对我最大的支持!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android 注解和反射 (入门以及使用) 的相关文章

  • 人工智能主要分支

    人工智能主要分支 1 主要分支介绍 通讯 感知与行动是现代人工智能的三个关键能力 xff0c 在这里我们将根据这些能力 应用对这三个技术领域进行介绍 xff1a 计算机视觉 CV 人脸识别 自然语言处理 NLP 语音识别 语义识别 在 NL
  • re.sub()用法详解

    源代码 参数及其意义 xff1a def sub pattern repl string count 61 0 flags 61 0 34 34 34 Return the string obtained by replacing the
  • BERT模型的详细介绍

    1 BERT 的基本原理是什么 xff1f BERT 来自 Google 的论文Pre training of Deep Bidirectional Transformers for Language Understanding xff0c
  • 自然语言处理(NLP)之使用TF-IDF模型计算文本相似度

    自然语言处理 NLP 之使用TF IDF模型计算文本相似度 所用数据集 xff1a ChnSentiCorp htl all csv 语料库即存放稀疏向量的列表 要注意的是 xff0c 搜索文本text与被检索的文档共用一个特征词词典 NL
  • HTTP 请求报文

    1 HTTP 请求报文介绍 HTTP最常见的请求报文有两种 GET 方式的请求报文POST 方式的请求报文 说明 GET 获取web服务器数据 比如获取新闻列表的数据 POST 向web服务器提交数据 比如登录的时候把用户名和密码发送给服务
  • 傅里叶变换公式

    傅里叶变换的目的 xff1a 有些信号在时域上是很难看出什么特征的 xff0c 但是如果变换到频域之后 xff0c 就很容易看出特征了 1 FS Fourier series 连续时间周期信号的傅里叶级数 xff0c 时域上任意连续的周期信
  • python修改闭包内使用的外部变量

    1 修改闭包内使用的外部变量 1 1 修改闭包内使用的外部变量的错误示例 定义一个外部函数 def func out num1 定义一个内部函数 def func inner num2 这里本意想要修改外部num1的值 xff0c 实际上是
  • re.search()用法详解

    re search xff1a 匹配整个字符串 xff0c 并返回第一个成功的匹配 如果匹配失败 xff0c 则返回None pattern 匹配的规则 string 要匹配的内容 flags 标志位 这个是可选的 就是可以不写 可以写 比
  • re.findall()用法详解

    re findall xff1a 函数返回包含所有匹配项的列表 返回string中所有与pattern相匹配的全部字串 xff0c 返回形式为数组 示例代码1 xff1a 打印所有的匹配项 import re s 61 34 Long li
  • Linux系统中创建虚拟环境详解

    1 方法一 1 1 安装虚拟环境的命令 xff1a sudo pip install virtualenv sudo pip install virtualenvwrapper 1 2 安装完虚拟环境后 xff0c 如果提示找不到mkvir
  • 使用python将图片改为灰度图或黑白图

    使用python将图片改为灰度图或黑白图有三种方式 xff0c 分别是是使用cv2库和PIL库来实现 xff0c 详细过程如下所示 1 使用cv2库将图片改为灰度图 在使用cv2进行读取原彩色图片时 xff0c 在里面添加一个参数cv2 I
  • 虚拟机中windows镜像下载与安装

    镜像文件下载 xff1a 链接 xff1a https pan baidu com s 1VKWMHHCGRwWXk2GpxyUp0A 提取码 xff1a shlg 注意 xff1a 虚拟机中的镜像和本地电脑系统安装的镜像是一样的 安装教程
  • Linux系统中安装elasticsearch详解

    官方网站 xff1a Install Elasticsearch from archive on Linux or MacOS Elasticsearch Guide 7 17 Elastic 一 安装命令 xff1a wget https
  • centos7系统查看防火墙状态

    查看方法 xff1a 1 利用systemctl查看 xff0c 该命令用于管理系统 xff0c 语法为 systemctl status firewalld xff1b 2 用firewall查看 xff0c 可以查看防火墙的默认状态 x
  • Docker中网络的使用和配置用法详解

    一 单个物理机中docker网络 1 1 Docker默认网桥 安装Docker 服务默认会创建一个 docker0 网桥 xff08 其上有一个 docker0 内部接口 xff09 xff0c 它在内核层连通了其他的物理或虚拟网卡 xf
  • mongo数据库中字符串型正负数值比较大小

    数据库中数据展示 xff1a 使用python代码实现 xff1a Requires pymongo 3 6 0 43 from pymongo import MongoClient client 61 MongoClient 34 mon
  • IDEA插件系列(3):Easy Javadoc插件——快速生成javadoc文档注释

    1 插件介绍 Easy Javadoc插件 能帮助开发者快速生成类 方法 属性等中文javadoc 2 安装方式 第一种安装方式是在线下载安装插件 第二种安装方式是使用离线插件进行安装 插件下载地址 xff1a https plugins
  • flask项目中内部接口调用其他内部接口操作

    1 requests 在 Flask 框架项目中 xff0c 可以通过使用 requests 模块来进行内部接口调用 requests 模块是 Python 中常用的 HTTP 请求库 xff0c 可以用于发送 HTTP 请求和处理响应 示
  • ElasticSearch删除索引中的数据(delete_by_query)

    1 删除两个月以前的数据 在 Elasticsearch 中 xff0c 要删除两个月以前的数据 xff0c 可以通过以下步骤 xff1a 计算当前时间的两个月前的日期 xff0c 可以使用 Python 的 datetime 模块来实现
  • ubuntu进入initramfs,系统黑屏

    ubantu黑屏 解决方法 解决方法 1 如果在initramfs模式输入reboot重启 xff0c 或者长按开机键强制关机重启 xff0c 然后选择ubuntu xff08 高级选项 xff09 中的修复模式 xff08 recover

随机推荐

  • You must specify at least three points for the robot footprint,reverting to previous footprint

    找到 costmap common params yaml xff0c 修改成如下形式 xff1a robot radius 0 20 distance a circular robot should be clear of the obs
  • 基于Anaconda3.8环境安装Python3.6

    基于Anaconda3 8环境安装Python3 6 1 通过如下命令查看当前已经装好的python环境 conda info e 2 通过python V 查看当前所处的版本 3 装好anaconda3 8以后想再安装一个python3
  • PX4无人机环境搭建

    PX4无人机资料开发 1 1 Ubuntu系统的安装及相关工具使用ubuntu 系统安装以及基础使用系统安装ubuntu基础使用常用工具使用git常用命令 1 2PX4开发环境搭建编译工具链的安装code安装使用 1 1 Ubuntu系统的
  • 3 FlightPlot安装使用方法

    FlightPlot安装使用方法 下载flightPlot源码下载切换openjdk 版本重启安装flightPlot 下载flightPlot源码 git clone recursive https github com PX4 Flig
  • 在Windows下安装TensorFlow和Keras

    在Windows下安装TensorFlow和Keras 1 安装 Anaconda3 5 1 0 Windows x86 64 exe xff0c 之前用的版本 xff0c 也可以下载更新的版本 绝大多数都选用默认选项即可 xff0c 遇到
  • 初学STM32

    编译出错 xff1a Error L6002U could not open file o No such file or directory 原因 xff1a 汉化出问题
  • 百度可视化工具Sugar简单介绍以及使用说明

    百度可视化工具Sugar简单介绍以及使用说明 介绍使用指南免费试用快速入门 使用流程使用示例 这是我个人的第一篇博客 最近因为工作原因 xff0c 需要了解百度可视化工具Sugar xff0c 因此在这里做个总结 xff0c 同时也为自己梳
  • 四小时Jsp期末作业速成——MyBlog个人博客系统(javaweb:非框架)

    MyBlog个人博客系统 xff08 javaweb 非框架 xff09 目录第一章 系统简介 31 1 背景及意义 31 2 开发目的 31 3 开发环境 3 第二章 系统设计 42 1 系统分析 42 1 1 系统需求分析 42 1 2
  • 【已解决】Ubantu问题记录:在连接网线的情况下ubuntu系统ping网关不通以及无法上网

    问题背景 xff1a 我们的服务器配置了两张在同一网段下的网卡 xff0c 卡 eno4 连接以太网ip xff1a 192 168 2 10 网关192 168 2 1 卡 eno2 ip xff1a 192 168 2 12 网关192
  • ros知识点

    工作空间 一个典型的ROS工作空间目录结构如下 所有ROS程序都必须放置在某个ROS工作空间 workspace 下 xff0c 我们在主目录下创建一个名为catkin ws的ROS工作空间 ROS工作的空间名字可以随便取 xff0c 一般
  • 我有一个IT梦

    介绍 作为一名大二的学生 xff0c 接触计算机基础技术近乎俩年 xff0c 俩年来我愈加发觉计算机是一门发展力很强的学科 它多式多样 xff0c 更像是一种挑战 xff0c 对于好强的我来说 xff0c 越来越着迷计算机的世界 纵然未知的
  • Mac 自动代理切换

    Mac 自动代理切换 背景 xff1a 工作有时需要用goole搜索 xff0c 所以会配置一下公司提供的HTTP和HTTPS代理 xff0c 但是下班之后回到家 xff0c 只有公司内网才能访问代理 xff0c 所以还需要把代理关掉 每次
  • 仅拉取git远程仓库中特定的单个分支

    结论 拉取git远程仓库中特定的单个分支的关键在于 xff1a 调用git clone时候 xff0c 添加 branch选项与 single branch git clone git clone克隆远程仓库时 xff0c 默认会依次做以下
  • Windows10通过网线连接树莓派ubuntu server系统

    Windows10通过网线连接树莓派ubuntu server系统 材料 xff1a 烧录ubuntu server 18 04镜像的树莓派 xff0c 网线一根 xff0c Window10电脑 操作 Windows10通过网线连接树莓派
  • 树莓派安装ROS操作系统并配置VNC连接

    树莓派 4B xff08 2G xff09 的准备工作 一 烧录ubuntu server 18 04 LTS镜像二 ubuntu系统安装桌面三 树莓派开启VNC连接1 使用dconf editor2 开启桌面共享服务3 Windows端下
  • Vscode配置树莓派ROS的开发环境

    树莓派安装ROS系统和远程连接配置我的这篇博客 附上连接 xff1a https blog csdn net weixin 44815966 article details 112697896 开发ros机器人时 xff0c 为了方便开发和
  • ROS操作系统 opencv-python读取摄像头+rviz可视化

    ROS操作系统 opencv python读取摄像头 43 rviz可视化 一 安装opencv python二 opencv读取摄像头三 图片转换为ROS图片格式并且在rviz显示 测试环境 xff1a 树莓派ubuntu 18 04 5
  • Git 报错:Connection closed by remote host. fatal: Could not read from remote repository.

    Git deploy 部署报错 xff1a ssh exchange identification Connection closed by remote host fatal Could not read from remote repo
  • RabbitMQ详解(二):Docker安装RabbitMQ

    一 安装并运行二 其他操作 在Docker上安装部署RabbitMQ方便快捷 xff0c 不需要额外安装Erlang环境 xff0c 所以写该篇文章先来介绍如何在Docker上部署RabbitMQ 一 安装并运行 1 在docker hub
  • android 注解和反射 (入门以及使用)

    先来看一看今天的效果 代码效果 效果不重要 重要的是代码 注解 官方解释 从JDK5开始 Java增加对元数据的支持 xff0c 也就是注解 xff0c 注解与注释是有一定区别的 xff0c 可以把注解理解为代码里的特殊标记 xff0c 这