java 获取所有带指定注解的类名_SXT DAY023 反射和注解

1. 反射机制介绍_Class对象获取

反射机制是 Java 的动态性之一

动态语言:在程序运行时,可以改变程序的结构或变量的 类型。

反射机制的常见作用

  1. 动态的加载类、动态的获取类的信息(属性,方法,构造 器)
  2. 动态构造对象
  3. 动态调用类和对象的任意方法、构造器
  4. 动态调用和处理属性
  5. 获取泛型信息
  6. 处理注解

java.lang.Class类 :表示正在运行的Java应用程序中的类和接口

获取Class对象的方式

  1. Class.forName(全限定类名);全限定类名==>包名+类名
  2. 类名.class
  3. 对象名.getClass()

练习代码

public class Test {public static void main(String[] args) {//获取Class对象try {//方法1:Class.forName("包名+类名")Class clazz=Class.forName("com.sxt.reflect.User");//方法2:类名.clazz
//			Class clazz=User.class;//方法3:通过调用 对象名.getClass()方法获取该类的Class信息
//			User user=new User();
//			Class clazz=user.getClass();String name=clazz.getName();  //获取类或接口的名称System.out.println("名称:"+name);String simpleName=clazz.getSimpleName();System.out.println("简单类名:"+simpleName);//获取声明的属性信息System.out.println("*****************属性信息******************");Field[] fields=clazz.getDeclaredFields(); //Field类封装了属性信息for (Field field : fields) {int fieldModifier=field.getModifiers();//获取修饰符  0:默认 1:private 2:public 4:protectedClass fieldType=field.getType();//获取类型String fieldName=field.getName();//获取名称System.out.println(fieldModifier+"----"+fieldType+"----"+fieldName);	}//获取构造方法System.out.println("**************构造方法****************");Constructor[] constructors=clazz.getDeclaredConstructors(); //获取构造器for (Constructor constructor : constructors) {int cModifier=constructor.getModifiers(); //获取构造器的修饰符String cName=constructor.getName();Class[] cs=constructor.getParameterTypes();System.out.println(cModifier+"---"+cName+"---"+Arrays.toString(cs));		}//获取方法信息System.out.println("***************方法信息***************");Method[] methods=clazz.getDeclaredMethods();for (Method method : methods) {int mModifier=method.getModifiers();Class returnType=method.getReturnType(); //获取返回值类型String mName=method.getName(); //获取方法名Class[] cs=method.getParameterTypes();System.out.println(mModifier+"---"+returnType+"---"+mName+"---"+Arrays.toString(cs));}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

运行结果

e2eaa93c27f1b9e782a3b17071b1b132.png

2 反射机制动态操作方法_属性_构造器

获取类的名字的方法

  • String getName() 获得全限定类名 包名+类名
  • String getSimpleName() 获得简单类名

获得类的属性的方法

  • Field getField(String fieldName) 得到公共的属性 对象
  • Field getDeclareField(String fieldName) 得到指定名称的 属性对象
  • Field []c.getDeclaredFields() 得到所有的属性 对象

获得类的方法

  • Method[] getDeclaredMethods() 得到所有声明的公共的方法对象
  • Method[] c.getMethods() 得到父类及本类中的公共的方法对象
  • Method getDeclaredMethod(String methodName, Class …type) 得到指定名称的 本类中公共的方法
  • Method getMethod(String methodName, Class type) 得到本类或父类中的公共的方法对象

获得构造方法

  • Constructor[] getDeclaredConstructors() 得到所有声明的公共的构造方法的对象
  • Constructor[] getConstructors() 得到公共的构造方法对象
  • Constructor getDeclaredConstructor(Class...type) 得到指定参数的公共的构造方法对象

练习代码

public class Test {public static void main(String[] args) throws Exception {String path="com.sxt.demo.User";//1.获取类的名称Class c=Class.forName(path);System.out.println("类的全名称:"+c.getName());System.out.println("类的名称:"+c.getSimpleName());//获取父类的Class对象Class cSuper=c.getSuperclass();System.out.println(cSuper.getName());System.out.println(cSuper.getSimpleName());//3.获取类的属性信息
//		Field f=c.getField("userId"); //  报错 只能获取公开的属性
//		System.out.println(f);Field[] fields=c.getFields();  //只能获取公开的属性System.out.println(fields.length);Field[] fields2=c.getDeclaredFields();System.out.println(fields2.length);for (Field field : fields2) {
//			System.out.println(field);  //调用了toString()方法System.out.println(field.getModifiers()+"t"+field.getType()+"t"+field.getName());}//3.获取类的方法信息Method[] methods=c.getDeclaredMethods();  //本类中的公共的方法对象System.out.println(methods.length);for (Method method : methods) {
//			System.out.println(method);System.out.println("访问权限:"+method.getModifiers());System.out.println("返回值类型:"+method.getReturnType());System.out.println("方法的名称:"+method.getName());//获取方法的参数Class[] cPara=method.getParameterTypes();for (Class c1 : cPara) {System.out.println(c1.getTypeName()+"t");}System.out.println("--------------------------");}System.out.println("========================");//4.获取类的构造器Constructor[] cons=c.getConstructors();for (Constructor constructor : cons) {System.out.println(constructor);}System.out.println("====================================");//根据参数获取指定的构造方法Constructor con=c.getConstructor(null);System.out.println(con);System.out.println("====================================");Constructor con2=c.getConstructor(int.class,String.class,String.class);System.out.println(con2);}
}

运行结果

620fd2bd84455dcdba38a2f6e75e16c0.png

练习代码

public class Test2 {public static void main(String[] args) {Class clazz;try {//如何动态创建对象clazz = Class.forName("com.sxt.reflect.User");Object object=clazz.newInstance();//通过反射动态创建对象System.out.println(object);System.out.println("------------访问属性---------------");Field userId=clazz.getDeclaredField("userId"); //获取指定的属性信息userId.setAccessible(true);userId.set(object, 1);//回调指定属性的赋值---->user.userId=1Object value=userId.get(object);//回调指定属性的getter方法进行赋值System.out.println("userId="+value);System.out.println("----------------回调方法---------------------");Method setUserName=clazz.getDeclaredMethod("setUserName", String.class);setUserName.invoke(object, "zhangsan"); //user.setUserName("zhangsan")Method getUserName=clazz.getDeclaredMethod("getUserName");//获取getUserName方法Object returnValue=getUserName.invoke(object); //user.getUserName()System.out.println(returnValue);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

运行结果

6ae9d003e6e60f805b8d0f9f67da0ba1.png

3 提高反射效率

通过 setAccessible 提高性能

a) setAccessible 启用和禁用访问安全检查的开关,值为 true 则指示反射的对象在使用时应该取消 Java 语言访 问检查,值为 false 则指示反射的对象不实施 Java 语 言访问检查,并不是为 true 就能访问为 false 就不能访问

b) 禁止安全检查,可以提高反射的运行速度

练习代码

public class Test3 {//方法的直接调用public static void test(){Object obj=new Object();long startTime=System.currentTimeMillis();for(int i=0;i<1000000000L;i++){obj.hashCode();}long endTime=System.currentTimeMillis();System.out.println("直接调用 用时:"+(endTime-startTime));}//未优化 使用反射机制回调public static void test2() throws Exception{Object obj=new Object();Class clazz=obj.getClass();Method method=clazz.getDeclaredMethod("hashCode");long startTime=System.currentTimeMillis();for(int i=0;i<1000000000L;i++){method.invoke(obj);}long endTime=System.currentTimeMillis();System.out.println("未优化 使用反射机制回调 用时:"+(endTime-startTime));}//优化 使用反射机制回调public static void test3() throws Exception{Object obj=new Object();Class clazz=obj.getClass();Method method=clazz.getDeclaredMethod("hashCode");long startTime=System.currentTimeMillis();method.setAccessible(true);for(int i=0;i<1000000000L;i++){method.invoke(obj);}long endTime=System.currentTimeMillis();System.out.println("优化 使用反射机制回调 用时:"+(endTime-startTime));}public static void main(String[] args) throws Exception {test();test2();test3();}}

运行结果

949589a047e7138d4cca93d69330b74f.png

4 反射操作泛型

Java 中的泛型仅仅是给编译器 javac 使用的,确保数据的安全性和免去强制类型转换的麻烦,但是一旦编译完成,所 有与泛型有关的类型全部擦除。

使用泛型直接读取泛型,是读取不到的,因为反射是操作 加载以后的类的。

Java新增的数据类型有

  • ParameterizedType: 表 示 一 种 参 数 化 的 类 型 ,比 如 Collection<String>,可以获取 String 信息
  • GenericArrayType:泛型数组类型
  • TypeVariable:各种类型变量的公共父接口
  • WildcardType:代表一种通配符类型表达式, 比如? extends Number,? super Integer (Wildcard 是一个单词,就是通配符)

练习代码

public class TestGeneric {public void test01(Map<String,User>map,List<User>list,String s){System.out.println("TestGeneric.test01");}public Map<Integer,User> test02(){System.out.println("TestGeneric.test01");return null;}public void test03(){System.out.println("TestGeneric.test01");}public static void main(String[] args) throws Exception {//获取test01方法的泛型参数信息NoSuchMethodExceptionClass c=TestGeneric.class;Method test01=c.getDeclaredMethod("test01", Map.class,List.class,String.class);//获取带泛型参数的类型Type[] types=test01.getGenericParameterTypes();System.out.println(types.length);for (Type type : types) {if(type instanceof ParameterizedType){ParameterizedType parameterizedType=(ParameterizedType) type;//ParameterizedType表示一个参数化类型Type[] genricType=parameterizedType.getActualTypeArguments();//返回一个表示此类型的实际类型参数的数组Type对象//遍历每一个泛型参数中的泛型的类型for (Type genType : genricType) {System.out.println("泛型类型:"+genType);}System.out.println("-------------------");}}System.out.println("-------------------------");//获取test01方法返回值的泛型信息Method test02=c.getDeclaredMethod("test02", null);Type returnType=test02.getGenericReturnType();//判断是否带有泛型if(returnType instanceof ParameterizedType){Type[] types2=((ParameterizedType)returnType).getActualTypeArguments();for (Type type : types2) {System.out.println("返回值的泛值类型:"+type);}}System.out.println("----------------------------");Method test03=c.getMethod("test03", null);Type returnType3=test03.getGenericReturnType();System.out.println(returnType3 instanceof ParameterizedType);}
}

运行结果

254c2c9d00624d2864b29aee0b5b2f7c.png

5 注解

注解的作用

不是程序本身,可以对程序作出解释。(这一点跟注释没 什么区别)

可以被其他程序(比如:编译器等)读取。(注解信息处理流程,是注解和注释的重大区别,如果没有注解信息处理流 程,则注解毫无意义)

注解的格式:注解是以”@注释名”在代码中存在,还可以添加一些参数 值,例如@SuppressWarnings(value=”unchecked”)。

注解可以附加在 package,class,method,field 等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程 实现对这些元素的访问。

内置的注解

  1. @Override :标识方法是重写的方法
  2. @Deprecated :标识的方法不建议使用
  3. @SuppressWarnings:用来抑制编译时的警告信息
  • @SuppressWarinings 需要提供参数才能正常使用,这些参数 都是已经定义好的,我们只需要选择就可以了。
  • @SuppressWarnings("unchecked") @SuppressWarnings(value={"unchecked","deprecation"})

70d7040dbf2b3f52d4ef76580f47ac2b.png

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

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

相关文章

tomcat勾连mysql_tomcat9.0启动脚本startup.bat的分析

1、 Apache Tomcat的下载和安装从Apache官网https://tomcat.apache.org/可以下载各种版本的tomcat软件&#xff0c;下载的文件格式可以是zip/tar.gz/exe形式的。如下图所示&#xff0c;在64位windows中使用tomcat&#xff0c;我们可以下载"64-bit Windows.zip",直接解…

安卓能硬改的手机机型_【每日新闻】小米11部分镜头参数爆料;华为重新采购手机零部件 重启4G手机生产...

数据铸造影响力关注每日行业热点资讯&#xff0c;掌握业界动态趋势&#xff0c;以下是今天的精彩内容&#xff1a;1、小米11部分镜头参数爆料&#xff1a;超大底50MP主摄&#xff0c;长焦达12MP或48MP2、华为重新采购手机零部件 重启4G手机生产1、小米11部分镜头参数爆料&#…

kafka集群为什么需要三个节点_大白话带你认识 Kafka

前言应大部分的小伙伴的要求&#xff0c;在Yarn之前先来一个kafka的小插曲&#xff0c;轻松愉快。一、Kafka基础消息系统的作用应该大部份小伙伴都清楚&#xff0c;用机油装箱举个例子所以消息系统就是如上图我们所说的仓库&#xff0c;能在中间过程作为缓存&#xff0c;并且实…

mysql对日期的操作_MySql对日期的操作

1、计算俩个日期之间所差的天数select datediff(2018-09-18,2018-09-01)2、计算日期是这周的星期几select dayofweek(2018-09-18)1.因为外国一般都是把星期天认为是一周的开始&#xff0c;所以用这种方法一般都得减去一天才是这周的星期几select date_format(2018-09-17,"…

sql移动加权计算利润_计算机视觉中的半监督学习

作者&#xff1a;Amit Chaudhary编译&#xff1a;ronghuaiyang导读图解半监督的各种方法的关键思想。计算机视觉的半监督学习方法在过去几年得到了快速发展。目前最先进的方法是在结构和损失函数方面对之前的工作进行了简化&#xff0c;以及引入了通过混合不同方案的混合方法。…

.net 启动mysql数据库连接_[ASP.net教程]mysql数据库连接方式(.net)

[ASP.net教程]mysql数据库连接方式(.net)0 2014-07-17 18:01:001.通过ado.net连接(数据库连接串中为中文貌似无法使用)需要添加MySql.Data.dll(可通过安装mysql-connector-net-6.8.3.mis获得)引用MySql.Data.dll调用方式string connectionString “serverlocalhost;port3306;da…

overflowhidden把内容遮住了怎么办_图片有水印怎么办?不用PS,有这4招就够了!...

图片是我们在做 PPT 时经常会使用到的高频元素。往往会在搜索引擎中搜到很多带有水印的图片&#xff0c;怎么办呢&#xff1f;固然 PS 等软件去水印很给力&#xff0c;但是对于连 PPT 都还没有用得很熟悉的同学&#xff0c;让他们再去下载安装 Photoshop 软件&#xff0c;仅仅只…

mysql开窗函数over_oracle分析函数技术详解(配上开窗函数over())

一、Oracle分析函数入门 分析函数是什么&#xff1f; 分析函数是Oracle专门用于 解决复杂报表统计需求 的功能强大的函数&#xff0c; 它可以在数据中进行分组然后计算基于组的某种统计 &#xff0c;并且每一组的每一行都可以返回一个统计。 分析函数和聚合函数的不同之处是什么…

传递给系统调用的数据区域太小怎么解决_一口气说出“分布式追踪系统”原理!...

“ 在微服务架构中&#xff0c;一次请求往往涉及到多个模块&#xff0c;多个中间件&#xff0c;多台机器的相互协作才能完成。图片来自 Pexels这一系列调用请求中&#xff0c;有些是串行的&#xff0c;有些是并行的&#xff0c;那么如何确定这个请求背后调用了哪些应用&#xf…

语义分割和实例分割_一文读懂语义分割与实例分割

以人工智能为导向的现代计算机视觉技术&#xff0c;在过去的十年中发生了巨大的变化。今天&#xff0c;它被广泛用于图像分类、人脸识别、物体检测、视频分析以及机器人及自动驾驶汽车中的图像处理等领域。图像分割技术是目前预测图像领域最热门的一项技术&#xff0c;原因在于…

游戏自审自查报告_开发的射箭小游戏上线了,分享一下我在开发过程中遇到的问题...

利用业余时间开发的微信小游戏-射箭救人质上线了&#xff0c;主要玩法就是操作弓箭射断绳子把人救下来就可以了。图片资源是我找一个朋友做的。开发过程不算太顺利。磕磕绊绊做了12关。希望大家支持下。谢谢。分享一下我在开发中遇到的问题和部分解决方案、希望对大家有所帮助。…

java 抛出异常的目的_Java实验八,异常

一.实验目的1. 掌握自定义异常类的编写&#xff1b;2. 掌握使用try-catch语句来处理异常。二.实验内容及要求车站检查危险品的设备&#xff0c;如果发现危险品会发出警告。编程模拟设备发现危险品&#xff1a;1. 编写一个Exception的子类DangerException&#xff0c;该子类可以…

postmapping注解_Swagger常用注解

在使用swagger时候如果掌握一些注解的使用&#xff0c;则在开发过程中测试的时候可以事半功倍&#xff0c;尤其在与前端技术进行联调&#xff0c;前端技术在访问swagger中的每个api时&#xff0c;可以很清楚的知道每个url对应的请求类型、参数类型、参数是否非必输、参数个数等…

java map 多个值_java 一个函数EnumMap返回多个值

在开发过程中&#xff0c;经常会有这种情况&#xff0c;就是一个函数需要返回多个值&#xff0c;这是一个问题&#xff01;&#xff01;网上这个问题的解决方法&#xff1a;1、使用map返回值&#xff1b;这个方法问题是&#xff0c;你并不知道如何返回值的key是什么&#xff0c…

调用别的方法的返回值_Spring boot如何实现异步调用

Spring boot如何实现异步调用异步调用:一个可以无需等待被调用函数的返回值就让操作继续进行的方法举个例子异步调用就是你 喊 你朋友吃饭 &#xff0c;你朋友说知道了 &#xff0c;待会忙完去找你 &#xff0c;你就去做别的了。同步调用就是你 喊 你朋友吃饭 &#xff0c;你朋…

照片识别出错_AI跨年龄人脸识别技术在跨年龄寻亲的应用简析

9月3日&#xff0c;央视财经《经济半小时》栏目播出了一段有关失踪儿童找回的视频新闻。在这则新闻中&#xff0c;跨年龄人脸识别技术是最为核心的功臣&#xff0c;深圳警方利用跨年龄人脸识别技术&#xff0c;根据一张3岁孩童的儿童照片找回了失踪了十几年的孩子&#xff0c;让…

分段线性判别法 java_线性判别分析(Linear Discriminant Analysis)(二)

4. 实例将3维空间上的球体样本点投影到二维上&#xff0c;W1相比W2能够获得更好的分离效果。PCA与LDA的降维对比&#xff1a;PCA选择样本点投影具有最大方差的方向&#xff0c;LDA选择分类性能最好的方向。LDA既然叫做线性判别分析&#xff0c;应该具有一定的预测功能&#xff…

软件测试用例_大话软件测试用例要素

我们经常都知道一个测试用例里面包含以下几个要素&#xff1a;1&#xff0c;用例编号2&#xff0c;模块3&#xff0c;场景4&#xff0c;用例名称5&#xff0c;前置条件6&#xff0c;测试等级7&#xff0c;操作步骤8&#xff0c;预期结果(需求要求的结果)9&#xff0c;实际结果1…

java中this图解_JAVA-初步认识-第七章-this关键字的使用场景和原理图解

一.this有什么用&#xff1f;我们用例子的形式来体现一下。下面的截图说明&#xff0c;给人对象一初始化的时候&#xff0c;赋值个姓名。赋值姓名的时候&#xff0c;拿n赋值给name&#xff0c;DOS显示创建对象时&#xff0c;构造函数初始化成功。在例子中&#xff0c;我们将“旺…

python汉诺塔_汉诺塔递归算法/搬金盘的婆罗门 - Python实现

汉诺塔递归算法/搬金盘的婆罗门 - Python实现版权声明本文节选自作者本人的图书《Python编程基础及应用》&#xff0c;高等教育出版社。本文可以在互联网上自由转载&#xff0c;但必须&#xff1a;注明出处(作者&#xff1a;海洋饼干叔叔)并包含指向本页面的链接。本文不可以以…