java:反射和注解

反射

在运行时动态地获取一个类的信息并操作该类的属性和方法的技术

可以解决一些常规编程中难以预知类的情况下的问题

eg:

实例化一个类:通过反射可以根据类名动态实例化一个对象

调用类的方法:通过反射可以根据方法名动态地调用一个类的方法

获取和设置类的字段:通过反射可以动态获取并操作一个类的资源,无视权限修饰符

反射提供了一种在编译时无法确定类信息的情况下,动态获取和操作类的能力

使得程序在运行时可以根据不同的情况来选择执行不同的方法,使程序更加灵活和可扩展.

反射应用-获取类的字节码对象

反射的步骤

1,加载类,获取类的字节码文件:Class对象

2,获取类的构造器:Constructor对象

3,获取类的成员变量:Field对象

4,获取类成员方法:Method对象

获取类的字节码对象方式

同一个类的字节码对象相同

推荐使用类的静态属性class获取类的字节码对象

class.forName()适合用于需要动态加载类的情况

getClass()较少使用

1,使用类的静态属性Class

Class<?> clazz = MyClass.class;

2,使用Object类的getClass()方法

Class<?> clazz = myObject.getClass();

3,使用Class.forName()方法

Class<?> clazz = Class.forName("com.example")

反射的应用

Field[] aClass.getDeclaredFields()
//获取字节码对象的全部属性
构造器对象构造
Constructor<?>[] getConstructors()
//获取全部构造器(只能获取public修饰的)
//返回构造器对象数组
Constructor<?>[] getDeclaredConstructors()
//获取全部构造器(只要存在就能拿到)
//返回构造器对象数组
Constructor<T> getConstructor(Class<?>...parameterTypes)
//获取某个构造器(只能获取public修饰的)
eg:.getConstructor(int.class,String.class)
Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes)
//获取某个构造器(只要存在就能拿到)
获取类构造器的作用:初始化对象返回
T newInstance(Object.....initargs)
//调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回
//返回一个对象
public void setAccessible(boolean flag)
//设置为true,表示禁止检查访问控制(暴力反射)
//取消权限检查
//构造器对象.setAccessible(true)
public String getName()
//返回带包类名
public String getSimpleName()
//返回类名
成员变量对象构造
Field getField(String name)
//返回类型中指定名称的public成员变量,name为变量名称
Field[] getFields
//返回该类型的所有public属性
Field getDeclaredField(String name)
//返回该类型中指定名称的属性,和属性权限无关
Field[] getDeclaredFields()
//返回该类型中的全部属性,与属性的访问级别无关
public String getName()
//返回属性名
public int getModifiers()
//获取属性的修饰符列表,返回的是数字,配合Modifier类的toString(int x)方法使用可以得到修饰符
public Class<?> getType()
//以Class类型,返回属性类型
配合Class类的getSimpleName()方法使用
public void set(Object obj,Object value)
//设置属性
public Object get(Object obj)
//读取属性值
方法对象构造
Method getMethod(String name,Class..params)
//返回实例中指定的public方法,name指定方法名称,params指定参数列表
Method[] getMethods()
//返回该实例中所有的public方法
Method getDeclaredMethod(String name,Class..params)
//返回实例中指定的方法,和权限修饰符无关
Method[] getDeclaredMethods()
//返回实例中全部的方法,和权限修饰符无关
Method方法
public String getName()
//返回方法名
public int getModifiers()
//获取方法修饰符列表
public Class<?> getReturnType()
//以Class类型,返回方法类型
配合Class类的getSimpleName()方法使用
public Class<?>[] getParameterTypes()
//返回方法的参数列表
public Object invoke(Object obj,Object...args)
//调用方法

注解

一种特殊的标记,可以被加在代码的某个地方,给代码提供额外的信息

可以用来帮助编译器,工具或者程序本身做一些特殊的处理.

使用场景:

1,编译时检查:帮助开发人员在编译期间发现潜在的错误,并提高了代码的可读性和可维护性

比如@Override

2,运行时处理:通过使用反射机制,可以在运行时获取和处理注解信息,例如通过注解实现自定义的依赖注入,AOP等功能

3,测试框架:使用注解来标记测试方法,测试类等,以便测试框架能够自动识别并执行测试

@Test

自定义注解:

1,使用@interface关键字定义一个注解类型

public @interface A{String a();int b() default 100;}@A

2,定义注解的属性:在注解类型中可以定义多个属性,用于存储注解的参数值.

类型可以是:基本数据类型,包装类,字符串类型,枚举类型,Class类型,注解类型和上述类型的数组

3,使用注解:在需要标记的代码元素上使用自定义注解.注解可以用于类,方法,字段等地方.可以为注解的属性赋予具体的值,或使用默认值.

注解参数的使用:注入代码元素


如果注解中只有一个属性需要赋值且这个属性叫value
在注解参数中可以只写value的值
@interface Test{String value();
}@Test("hello")

4,处理注解:如果需要对注解进行进一步处理,可以使用注解解析器.注解处理器可以在运行时扫描代码,提取注解信息并进行相应的处理.

通过自定义注解,我们可以在代码中通过注解来标记和传递额外的数据信息.

元注解

用来修饰其他注解的注解.

可以对注解进行更深入的描述和控制,提供了更多的灵活性和功能.

元注解的作用

对其他注解进行描述和控制.

告诉编译器和运行时环境如何处理注解

通过元注解,我们可以指定注解的生命周期(在源代码,编译后的class文件或运行时保留)

和作用目标(类,字段,方法等)

由java提供

常见元注解
@Target(ElementType.TYPE)
//声明注解使用的位置
1,TYPE,,接口
2,FIELD,成员变量
3,METHOD,成员方法
4,PARAMETER,方法参数
5,CONSTRUCTOR,构造器
6,LOCAL_VARIBLE,局部变量
@Retention(RetentionPolicy.RUNTIME)
//声明注解的生命周期
1,SOURCE 只作用在源码阶段,字节码文件中不存在
2,CLASS(默认值) 保留到字节码文件阶段,运行阶段不存在
3,RUNTIME(开发常用) 一直保留到运行阶段

使用场景

@MyTest(value = "testClass",bbb={"b"})
class Demo{@MyTest(value = "testMethod",bbb={"a"})public void test(){}
}@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyTest{String value();double aaa() default 100;String[] bbb();
}

注解解析

是指对java程序中的注解进行解析和处理的过程

包含两个方面

注解的读取

通过反射机制获取程序中的注解信息.

通过反射可以获取到类,方法,字段等的注解,并可以获取注解中定义的属性值

注解的处理

根据注解的信息执行相应的操作

如果需要通过反射机制获取注解信息,注解的生命周期类型必须是RetentionPolicy.RUNTIME

解析注解的方法

先用反射获取需要解析的对象

public Annotation[] getDeclaredAnnotations()
//获取当前对象上面的注解
public T getDeclaredAnnotation(Class<T> annotationClass)
//获取指定的注解对象
public boolean isAnnotationPresent(Class<Annotation> annotationClass)
//判断当前对象上是否存在某个注解

Class,Method,Field,Constructor都实现了AnnotatedElement接口,都拥有解析注解的能力.

注解中的属性值即为解析出的注解对象属性值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/146.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【笔记】下云的一小步尝试——内网穿透

云上的世界很精彩&#xff0c;可是越来越贵&#xff0c;系统也越来越臃肿&#xff1b;如果我只需要云提供网络接入&#xff0c;流量大的时候CDN和load balancer就够了&#xff0c;其他的业务只想在内部公开&#xff0c;那么就得将一些需要内部化的服务下云了。用自己的数据中心…

ADOP-400G光模块问题发布会

前沿光学&#xff08;ADOP&#xff09;400G光模块为客户提供各种超高密度的400G以太网连接方案&#xff0c;广泛应用于数据中心、企业网和服务提供商。 &#x1f4e3;&#x1f4e3;以下一些问题是我们新一代400G光模块常能遇见问题&#xff0c;所以我们决定在这里开一场小小的…

书生·浦语大模型第二期实战营(4)笔记

Finetune 为什么要微调 适应下游任务 两种微调范式 上面的是增量训练 下面的是指令微调 数据格式 微调方案 lora&#xff1a; 在基座模型的基础上再套用一个小模型 XTuner 简介 快速上手 LnternLM2 1.8B 多模态LLM

qt-C++笔记之获取当前文件名所在路径并拼接出新文件路径的一种方法

qt-C笔记之获取当前文件名所在路径并拼接出新文件路径的一种方法 code review! 运行 在 Qt 框架中&#xff0c;QFileInfo 和 QDir类通常用于文件系统信息的查询和目录管理。下面是按照这样一种新颖的步骤来拼接新文件路径的示例代码&#xff1a; #include <QFileInfo>…

智慧煤矿/智慧矿区视频汇聚存储与安全风险智能分析平台建设思路

一、建设背景 目前我国非常重视煤矿安全生产&#xff0c;并投入大量资金用于煤矿安全综合远程监控系统的研发。视频监控系统作为实现煤矿智能化无人开采的关键系统与煤矿安全生产的多系统协同分析与处理的关键信息源&#xff0c;在智慧矿山管控平台的建设中发挥着重要的作用。…

Java对象转xml(Object to Xml)

目录 第一章、Java对象转xml1.1&#xff09;Java实体类1.2&#xff09;Xml中需要包含的字段1.3&#xff09;设置根标签和属性序列化方式1.4&#xff09;使用JAXBContext和Marshaller进行转换 友情提醒: 先看目录&#xff0c;了解文章结构&#xff0c;点击目录可跳转到文章指定…

数据结构书后习题

p17 1&#xff0c; 个人解答&#xff1a; int DeleteMinElem(SqList &L,int &min) {int j 0;if (L.length 0){printf("error!");return 0;}int min L.data[0];for (int i 1; i < L.length; i){if (L.data[i] < min){min L.data[i];j i;}}L.dat…

cesium 调整3dtiles的位置 世界坐标下 相对坐标下 平移矩阵

cesium调整3dtiles的位置用到的是平移矩阵&#xff0c;原理是在世界坐标系中用偏移点减去原始点得到一个平移向量&#xff0c;再根据这个向量得到平移矩阵。 原始点&#xff1a;一般是模型的中心点位置&#xff0c;可通过模型的包围盒得到偏移点&#xff1a;可分为两种情况&…

Docker八股总结

1. 容器和虚拟机的区别 传统虚拟机技术是虚拟出一套硬件后&#xff0c;在其上运行一个完整操作系统&#xff0c;在该系统上再运行所需应用进程&#xff1b;而容器内的应用进程直接运行于宿主的内核&#xff0c;容器内没有自己的内核&#xff0c;而且也没有进行硬件虚拟。因此容…

【MATLAB源码-第191期】基于matlab的4QAM系统相位偏移估计EOS算法仿真,对比补偿前后的星座图误码率。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 引言 M-QAM调制技术的重要性 现代通信系统追求的是更高的数据传输速率和更有效的频谱利用率。M-QAM调制技术&#xff0c;作为一种高效的调制方案&#xff0c;能够通过在相同的带宽条件下传输更多的数据位来满足这一需求。…

代码随想录 回溯—组合

递归函数三部曲&#xff1a; 递归函数参数返回值 确定终止条件 单层递归逻辑 思路&#xff1a;result存组合结果&#xff0c;path存一个结果生成的路径&#xff0c;回溯函数的参数除了所传进去的n和k&#xff0c;还要传进一个起始点startIndex&#xff0c;这就是确定了参数返…

EasyImage2.0 简单图床开源 多功能 简单易用图床系统源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 支持API 支持仅登录后上传 支持设置图片质量 支持压缩图片大小 支持文字/图片水印 支持设置图片指定宽/高 支持上传图片转换为指定格式 支持限制最低宽度/高度上传 支持上传其他文件格…

物联网与服务器有什么样的联系?

当今物联网是比较火的词汇&#xff0c;那么物联网是什么呢&#xff1f;物联网对人们的生活会产生哪些影响呢&#xff1f;。说的通俗一点物联网就是将设 备接入网络&#xff0c;实现设备智能化。那么物联网与服务器又有着怎样的联系呢&#xff1f;下面我们就一起来探讨一下这个问…

Lua中文语言编程源码-第九节,更改ltablib.c 表格操作函数, 使Lua加载中文库关键词(执行诸如查找、插入、删除、排序等表格操作)

源码已经更新在CSDN的码库里&#xff1a; git clone https://gitcode.com/funsion/CLua.git 在src文件夹下的ltablib.c 表格操作函数&#xff0c;此模块是C语言编写的&#xff0c;是Lua语言中的一个库文件&#xff0c;主要用来提供表格操作的功能。 该库提供了许多函数&…

【免费题库】华为OD机试 - 字符串排序(Java JS Python C C++)

须知 哈喽,本题库完全免费,收费是为了防止被爬,大家订阅专栏后可以私信联系退款。感谢支持 文章目录 须知题目描述用例1解题思路:Java代码:JS代码:Python代码:C代码:C++代码:题目描述 排序规则: 单词中字母比较不区分大小写,两个单词先以第一个字母作为排序的基准…

突破“三个九”!离子阱量子计算再创新高

如果把量子计算比作一场球赛&#xff0c;Quantinuum无疑又打了一记漂亮的好球。实际上&#xff0c;结合今年春季在量子体积、逻辑量子比特和布线问题等方面的进展&#xff0c;这个团队已经接近于完成一场完美的比赛。 3月&#xff0c;Quantinuum的研究人员证明了QCCD架构的可扩…

Vue-router 路由钩子在生命周期的体现

一、Vue-Router导航守卫 有的时候&#xff0c;需要通过路由来进行一些操作&#xff0c;比如最常见的登录权限验证&#xff0c;当用户满足条件时&#xff0c;才让其进入导航&#xff0c;否则就取消跳转&#xff0c;并跳到登录页面让其登录。 为此有很多种方法可以植入路由的导航…

RESTful API构建 web 应用程序

RESTful API&#xff08;Representational State Transfer&#xff09;是一种用于构建网络服务的架构风格。它基于 HTTP 协议&#xff0c;并采用资源的概念来定义和管理 API。在 RESTful API 中&#xff0c;每个资源都有一个唯一的标识符&#xff08;URI&#xff09;&#xff0…

如何使用ModStart搭建一个文库系统

使用ModStart搭建一个文库系统涉及多个步骤&#xff0c;以下是一个基本的指南&#xff1a; 环境准备&#xff1a; 确保你的服务器环境已经安装了PHP和MySQL&#xff0c;并且它们的版本满足ModStart的要求。下载并安装ModStart。你可以从官方网站或GitHub上下载最新版本的ModSta…

Linux学习之路 -- PCB介绍 -- 进程优先级

1、什么是优先级&#xff1f; 进程需要某一种资源&#xff0c;而系统要通过特定的方式来决定谁先获得这些资源&#xff0c;而系统的做法就是给不同的进程安排不同的优先级。让优先级高的进程先享有一些资源。 2、为什么要有优先级 因为资源的缺乏&#xff0c;所以系统的才会…