java反射与注解_java反射动态删除注解-程序员宅基地

技术标签: java  

反射

1.机制
在运行状态(动态)中对于任意一个类,都能够知道这个类的所有属性和方法
对于任意一个对象都能够调用它的任意方法和属性

2.功能
1.在运行时获取任意一个对象修饰符,泛型,父类/实现的接口/注解等
2.运行时构造任意一个类的对象
3.运行时获取任意一个类所具有的构造方法,成员变量和方法
4.运行时访问任意一个对象的成员变量和方法

3.应用

(1)通过类的全名创建类实例来使用外部用户定义的类
(2)开发类浏览器和智能IDE
(3)在测试工具中检测类的内部结构
(4)在框架开发中用于实现配置信息的处理

使用反射

1.class类
java.lang.Class是所有Reflection API的切入点,是所有反射操作的入口

对于每种类型的对象java虚拟机都会实例化一个不可变的java.lang.Class实例
每个对象都是引用或者原始类型

1.java.lang.Class.java类对象
2.java.lang.reflect.Constructor.java类的构造器对象
3.java.lang.reflect.Method.java类的方法对象
4.java.lang.reflect.Field.java类的属性对象 Field字段也即成员变量

一/获取Class实例的三种方法
1.对象.getClass()
2.类型名.class
3.ClassforName()(最常用)
二/获取类的成员
java.lang.reflect.Field.java类,一个Field提供类或接口中的一个成员变量的信息,可以动态访问
public Field getDeclaredField(String name)//根据名字获取类中定义的成员变量,不包括继承父类的成员

public Field[] getDeclaredFields()//获取类中声明的所有成员变量,返回Field[]类型,不含继承父类的成员
无Declared包含继承父类的成员

访问成员变量,成员方法和构造方法的方法
1.列出所有成员的方法
2.根据名字搜索特定成员的方法
3.获取类的成员方法
4.获取类的构造方法
5.调用成员方法

//使用反射调用对象的方法
//使用反射根据方法名,和参数类型、参数数量来获取具体某个方法
Method m=c.getDeclaredMethod(methodname, Class.forName(mptypes[0]));//String.class
//方法的调用,调用o对象的m方法,方法的实际参数是mp1,mo是方法调用的返回值
Object mo=m.invoke(o,mp1);
//o.setName("xiaohong");
System.out.println(mo);
//调用了o对象名为setAge,参数有1个,类型是int型的方法,实际参数是21
m=c.getDeclaredMethod("setAge", int.class);
m.invoke(o, 21);
System.out.println(o);
/*Method m=c.getDeclaredMethod(methodname);
Object mo=m.invoke(o);
System.out.println(mo);
System.out.println(f.get(o));*/
不得不用反射
第一个参数是调用方法的类实例
	(静态方法)第一个参数为null
后面几个参数是该方法的参数

6.用反射的方式给对象的属性设置值,获取对象的属性值

//使用反射访问类对象的属性(给属性设置值,获取属性的值)
Field f=c.getDeclaredField(fieldname);//根据Field名,获得Field对象
f.setAccessible(true);
f.set(o,fvalue);//o.name=“xiaolin”;使用反射给o对象的f代表的属性设置值为发value的值
System.out.println(f.get(o));//获取o对象的f属性对应的值,并输出

1.给定类的实例
2.通常情况下是因为常规方法无法设置对象的属性值才迫不得已用反射
3.这方法违反了类的封装性的设计意图,耗费额外的系统开销

7通过Constructor实例创建对象
(1)关键字new

Object o=c.newInstance();//Student o=new Student();

(2)第二种用反射创建类对象的方法,先获取具体的Constructor,再用Constructor去创建对象

Constructor con=c.getDeclaredConstructor(String.class,int.class);
//根据构造方法参数类型来获取某个构造方法
Object o1=con.newInstance("Mary",20);
//用Constructor创建类对象,相当于Student o1=new Student("Mary",20);
System.out.println(o1);

//第一种用反射创建类对象的方法,相当于调用类的无参数构造方法
方法1调用非私有的无参构造,可以抛出构造方法的异常
方法2形参是(Object… obj)调用类的任何一个构造方法。用InnovationTargetException封装异常来抛出

1.反射增加了JVM的系统开销,
2.反射允许访问私有成员,打破了封装,可能破坏可移植性。
总结:能不用就不用

Class c=Class.forName(classname);

//根据类名字符串获得类对应的Class实例
在这里插入图片描述
包含继承父类成员

访问对象的属性(给属性设置值,获取属性的值)

//使用反射访问类对象的属性(给属性设置值,获取属性的值)
Field f=c.getDeclaredField(fieldname);//根据Field名,获得Field对象
f.setAccessible(true);
f.set(o,fvalue);//o.name="xiaolin";使用反射给o对象的f代表的属性设置值为fvalue的值
System.out.println(f.get(o));//获取o对象的f属性对应的值,并输出

在这里插入图片描述
用获取的类型来进行获取修饰符
在这里插入图片描述
这个是获取类声明所有的成员变量返回TypeVariable<?>接口类型
继承了多个接口
方法有getName()
getTypeParameters();
格式化成字符串后getName()
在这里插入图片描述super父类
类型Class在这里插入图片描述接口interfaces类型Type
getGeneritcinterfaces()c
ToString()在这里插入图片描述获取类的注解类型Annotation
getAnnotation()
toString()在这里插入图片描述
获取类的构造函数
Constructor返回类型
getDeclaredConstructor();
toGenericString()
在这里插入图片描述
获取类的成员变量
Field[]返回类型(成员变量类型)
getDeclaredFields();
ToGenericString();

在这里插入图片描述
Method[]返回类型
getMethods();
获取类的公有方法toGener
icString()

import java.lang.reflect.TypeVariable;
import java.lang.reflect.Modifier;
Modifier/TypeVariable要import才能使用
Class可以不用import
在这里插入图片描述
c.getModifiers()
%n这个参数必须是一个有符号整数的指针,它存储它出现之前打印的所有字符数。
.format(" ")格式化字符串
通过调用invoke方法来执行对象的某个方法
在这里插入图片描述

图片源于https://www.cnblogs.com/qingchen521/p/8575761.html

注解

1.概念

一个元数据形式,提供有关程序的数据,该数据不属于程序本身,注释对于对其注释的代码的操作没有直接影响

注解的语法
@注解类型名

用途:
1.编译前:为编译器提供编译检查的依据,辅助检查代码错误或抑制检查异常。
2.编译中或发布时:给编译器提供信息生成代码或给其他工具提供信息生成文档等。
3.运行时:在运行过程中提供信息给解释器,辅助程序执行。
注解经常和反射结合起来用,多用于框架中

五个基本注解
@Override
@Deprecated
@Suppress Warnings
@Safe Varargs
@FunctionalInterface

2.内置的注解

1.Override
位置:在方法前
作用:1.表示重写父类的方法
2.如果重写有错误就报错
可以强制子类必须覆盖父类的方法

2.@Deprecated过时的警告
since属性指定从哪个版本开始,forRemoval指定该API将来会被删除
在这里插入图片描述

3.@SuppressWarnings
抑制编译器警告
在这里插入图片描述
4.SafeVarargs
堆异常警告
//给一个不带泛型的对象赋给一个带泛型的变量的时候往往就会发生堆污染
堆污染警告
faltyMethod发出"堆污染警告"
1.使用@SafeVarargs修饰引发该警告的方法或构造器
2.@SuppressWarning(“unchecked”)修饰
3.编译时用-Xlint:varags选项

函数式接口
@FunctionalInterface
如果接口中只有一个抽象方法
该接口就是函数式接口
在这里插入图片描述

自定义注解

修饰符:@interface(自动继承java.lang.annotation.Annotation接口)@元注解

元注解

元注解负责注解其他注解

Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)

4个标准的meta-annotation类型:
1.@Target
修饰注解定义
Annotation所修饰的对象范围
取值(ElementType)有:
1.CONSTRUCTOR:用于描述构造器   
2.FIELD:用于描述域   
3.LOCAL_VARIABLE:用于描述局部变量   
4.METHOD:用于描述方法   
5.PACKAGE:用于描述包   
6.PARAMETER:用于描述参数   
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
8.ANNOTATION_TYPE:指定该策略的注解只能修饰构造器
2.@Retention
指定Annotation被保留的时间长短
必须为value成员变量指定值、
value成员变量的值只能是下面三个
1. RetentionPolicy.CLASS
编译器将把注解记录在class文件中,当运行java程序的时候JVM不可获取注解信息,这是默认值
2. RetentionPolicy.RUNTIME
编译器把注解记录在class文件中,当运行java程序的时候,JVM可以获取注解信息,可以通过反射获取信息。
3. RetentionPolicy.SOURCE
注解保留在源代码中,编译器直接丢掉这种注解

			如果需要通过反射获取注解信息,就需要将value的属性值设置为RetentionPolicy.RUNTIME的@Retention(value=RetionPolicy.RUNTIME)
			public interface Testable

@Retention (RetentionPolicy.SOURCE)
public @interface Testable{}

3.@Documented
用于指定被元注解修饰的注解类将被javadoc工具提取成文档
如果定义注解类的时候用了@Documented修饰,则所有使用该注解修饰的程序元素的API文档将会包含该注释说明
4.@Inherited
被修饰的注解将具有继承性

提取注解信息

SuppressWarnings(“unchecked”)忽略编译器的警告
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_52024881/article/details/119087623

智能推荐

ElasticSearch为啥那么快?总结一下_elasticsearch 为什么是准实时的-程序员宅基地

文章浏览阅读1.8k次。思考问题:为什么搜索是近实时的?为什么文档的CRUD是实时的?下图是云上一个集群集群中有多个节点索引可以跨节点组成在一个索引下,存储着分片,分片实际上是Lucene Index.Shard分片里面存储着segment,可以看成是Lucene内部的mini-index那么segment有啥呢?Inverted Index主要包括两部分:倒排索引1.一个有序的数..._elasticsearch 为什么是准实时的

Python Flask,数据库,SQLAlchemy,数据库迁移 (根据模型类自动生成数据库表),Flask-Migrate_python sqlalchemy 数据迁移-程序员宅基地

文章浏览阅读2.4k次。在开发过程中,需要修改数据库模型类,而且还要在修改之后更新数据库。最直接的方式就是删除旧表,但这样会丢失数据。更好的解决办法是使用数据库迁移框架,它可以追踪数据库模型的变化,然后把变动应用到数据库中。在Flask中可以使用Flask-Migrate扩展,来实现数据库迁移。并且集成到Flask-Script中,所有操作通过命令来完成。安装flask_script包: pip instal..._python sqlalchemy 数据迁移

web网页设计期末课程大作业:漫画网站设计——我的英雄(5页)学生个人单页面网页作业 学生网页设计成品 静态HTML网页单页制作_web网页设计作业-程序员宅基地

文章浏览阅读709次,点赞23次,收藏7次。1网页简介:此作品为学生个人主页网页设计题材,HTML+CSS 布局制作,web前端期末大作业,大学生网页设计作业源码,这是一个不错的网页制作,画面精明,代码为简单学生水平, 非常适合初学者学习使用。2.网页编辑等任意html编辑软件进行运行及修改编辑等操作)。3.知识应用:技术方面主要应用了网页知识中的: Div+CSS、鼠标滑过特效、Table、导航栏效果、Banner、表单、二级三级页面等,视频、 音频元素 、Flash,同时设计了Logo(源文件)所需的知识点。..._web网页设计作业

PostgreSQL(三) 模式匹配(正则和LIKE)_gp数据库正则匹配-程序员宅基地

文章浏览阅读2.9k次。LIKE, POSIX正则, SIMILAR TO正则_gp数据库正则匹配

西瓜书第9章 聚类 笔记_西瓜书聚类的ss-程序员宅基地

文章浏览阅读195次。性能度量(有效性指标):用于评估聚类好坏_西瓜书聚类的ss

linux 源代码gcc安装,Linux下GCC源码方式安装过程-程序员宅基地

文章浏览阅读331次。今天上午上机,任务是在Linux下熟悉以源码方式的软件安装,我们的目的就是将GCC4.1.1以源码的方式安装成功。这个东东之前也装过。是边在网上查边装的,装完能用就行了,也没总结过。今天做完后想总结一下,便于以后用。首先呢,就是下源码了, http://ftp.gnu.org/gnu/gcc/gcc-4.1.1/到这儿下一个,我们实验要求是下载这个,所以我就用的它,完全可以下一个最新的玩玩嘛,下完..._linux 源码安装gcc 博客

随便推点

什么是容器???_什么是容器?visual basic哪些对象可以用作容器?-程序员宅基地

文章浏览阅读2.4k次。今天研究一下什么是容器??? 那么容器到底是什么呢?在csdn的论坛上人们众说纷纭:1)容器 和原意放东西的地方差不多,把链表了,数组一类的结构称作容器!2)在面向对象的编程中,你所面对的东西都叫对象,是想一下,来存放对象集合的东西叫什么?3)从特征上来看,容器主要分为顺序容器(list和vector)和关联容器(map和set)。通俗地说,vector就是可以自_什么是容器?visual basic哪些对象可以用作容器?

Linux-程序员宅基地

文章浏览阅读316次,点赞8次,收藏7次。个人桌面操作系统:Windows、macOS服务器操作系统:Linux。

C++——定义一个 Book(图书)类_c++写一个book类-程序员宅基地

C++:定义一个 Book(图书)类,包括book_name、price和number三个数据成员,以及display()、borrow()和restore()三个成员函数。示例代码展示了如何创建一个Book对象并调用其成员函数进行显示、借阅和归还操作。

听说!Art-DAQ实现了与LabVIEW的无缝连接_基于ni-visa的art-daq驱动-程序员宅基地

文章浏览阅读530次,点赞9次,收藏12次。与此同时我们的板卡程序可以按照一定的规范来编写,可以实现同一个程序,适用于所有拥有相同硬件功能的Art-DAQ板卡,这个对于我们来说也是节省了很多时间,不必再去为每一个采集卡配不同语言的程序,可以实现每一种编程语言配好程序就行,不需要针对的是每一张采集卡。这对于习惯使用NI板卡编程的客户是一个很好的消息,客户这边看到我们的程序,会有一种熟悉感,客户那边使用我们的板卡也可以有一个很好的过渡,很快能投入使用,节省了客户的时间与经济成本。持续不断地获取行业新技术,完善自主知识产权产品的研发,为客户提供优质服务。_基于ni-visa的art-daq驱动

重构: 改善既有代码的设计_重构:改善既有代码的设计代码说明-程序员宅基地

文章浏览阅读363次。重构_重构:改善既有代码的设计代码说明

人工智能安全-6-SQL注入检测_正则检测字符串是否存在sql注入-程序员宅基地

文章浏览阅读1.4k次,点赞4次,收藏11次。SQLIA:SQL injection attack SQL 注入攻击是一个简单且被广泛理解的技术,它把 SQL 查询片段插入到 GET 或 POST 参数里提交到网络应用。由于SQL数据库在Web应用中的普遍性,使得SQL攻击在很多网站上都可以进行。并且这种攻击技术的难度不高,但攻击变换手段众多,危害性大,使得它成为网络安全中比较棘手的安全问题。_正则检测字符串是否存在sql注入

推荐文章

热门文章

相关标签