java 反射调用方法_java的反射机制,以及通过反射获取方法,变量等操作

我们应用会用到反射这个知识点,肯定是想要在运行时得到类的信息,根据类的那些信息去做一些特定的操作。那么,首先无疑就是得到类的信息,在JDK中提供了Class对象来保存类的信息。所以,反射的第一步就是得到Class对象。在JDK中提供了两种方式得到Class对象。第一种,如果编写代码的时候,就知道Class的名字,可以直接用如下方式得到Class对象:

	//第一种,如果编写代码的时候,就知道Class的名字,可以直接用如下方式得到Class对象:Class exampleObjectClass = ExampleObject.class;//第二种,如果在编写代码的时候,不知道类的名字,但是在运行时的时候,可以得到一个类名的字符串,可以用如下的方式获取Class对象://注意,此方法需要有2个条件,第一,forName中的字符串必须是全限定名,第二,//这个Class类必须在classpath的路径下面,因为该方法会抛出ClassNotFoundException的异常。Class exampleObjectClass2 = Class.forName("com.team.frame.fanshe.ExampleObject");


下面介绍通过反射可以获取那些信息:

1. 得到类的名字

	/*** 得到类的名字* 类的名字有两种方式得到,一种是getName(),一种是getSimpleName()。* 第一种得到的是全限定名,第二种得到的是这个类的名字,不带包名。看下面的例子:Class对象,已经通过上面的代码得到了。*/String fullClassName = exampleObjectClass.getName();String simpleClassName = exampleObjectClass.getSimpleName();System.out.println(fullClassName);System.out.println(simpleClassName);

2. 得到类的包名、父类和实现的接口

    //得到包信息Package aPackage = exampleObjectClass.getPackage();System.out.println(aPackage);//得到父类Class superClass = exampleObjectClass.getSuperclass();System.out.println(superClass.getSimpleName());//判断父类是否是抽象类boolean abstract1 = Modifier.isAbstract(superClass.getModifiers());//我们还可以得到父类实现的接口Class[] interfaces = superClass.getInterfaces();System.out.println("父类的接口" + interfaces[0]);

3. 利用Java反射可以得到一个类的构造器,并根据构造器,在运行时动态的创建一个对象

    Constructor[] constructors = exampleObjectClass.getConstructors();for(Constructor cos:constructors){System.out.println(cos.toString());}//如果,事先知道要访问的构造方法的参数类型,可以利用如下方法获取指定的构造方法,例子如下:Constructor constructor = exampleObjectClass.getConstructor(String.class);System.out.println(constructor);//此外,如果我们不知道构造器的参数,只能得到所有的构造器对象,那么可以用如下方式得到每一个构造器对想的参数:Constructor[] constructors2 = exampleObjectClass.getConstructors();for(Constructor cos2:constructors2){Class[] parameterTypes = cos2.getParameterTypes();for(Class cla:parameterTypes){System.out.println("参数类型"+cla.toString());}}//根据构造器创建一个对象//这个创建对象的方式有2个条件,第一是通过有参构造器创建的,第二,构造器对象必须通过传入参数信息的getConstructor得到。//第一个条件,对于无参构造方法就可以创建的对象,不需要得到构造器对象,直接Class对象调用newInstance()方法就直接创建对象。//第二个条件,构造器对象必须通过exampleObjectClass.getConstructor(String.class);这种形式得到。如果通过getConstructors得到构造器数组//,然后调用指定的构造器对象去创建对象在JDK1.8是会错的。但是JDK1.6是正常的Constructor constructor2 = exampleObjectClass.getConstructor(int.class,Integer.class);Object newInstance = constructor2.newInstance(1,100);System.out.println(newInstance.toString());

4. 利用Java反射可以在运行时得到一个类的变量信息

    /*** 变量* 利用Java反射可以在运行时得到一个类的变量信息,并且可以根据上面讲的方式,创建一个对象,设置他的变量值。首先,通过如下方法,得到所有public的变量:*/Field[] fields = exampleObjectClass.getFields();for(Field fi:fields){System.out.println("变量为"+fi.toString());}//和构造器一样的得到方式一样,我们可以指定一个参数名,然后得到指定的变量:Field field = exampleObjectClass.getField("age");System.out.println(field.toString());//更改变量的值Constructor constructor1 = exampleObjectClass.getConstructor(String.class);ExampleObject newInstance2 = (ExampleObject)constructor1.newInstance("heihei");System.out.println("原来的age"+newInstance2.getAge());field.set(newInstance2, 10);System.out.println("修改后age"+newInstance2.getAge());

5. Java反射给我们除了给我们提供类的变量信息之外,当然也给我们提供了方法的信息

    /*** 方法* Java反射给我们除了给我们提供类的变量信息之外,当然也给我们提供了方法的信息,* 反射可以让我们得到方法名,方法的参数,方法的返回类型,以及调用方法等功能。*/Method[] methods = exampleObjectClass.getMethods();for(Method me:methods){System.out.println("method="+me.getName());}//根据参数获得具体方法Method method = exampleObjectClass.getMethod("setAge", int.class);System.out.println(method.getName());//获取方法的参数类型Class<?>[] parameterTypes = method.getParameterTypes();for(Class clz:parameterTypes){System.out.println("参数名"+clz.getName());System.out.println("类型"+clz.getTypeParameters());}//获得方法返回类型的Class<?> returnType = method.getReturnType();//此外,Java反射支持通过invoke调用得到的方法。例子如下://nvoke第一个参数是这个对象,第二个参数是变长数组,传入该方法的参数。和Field对象同样,对于静态方法同样,可以传入null,调用静态方法。method.invoke(exampleObjectClass.newInstance(), 1);

6. Java给我们提供了在运行时获取类的注解信息,可以得到类注解,方法注解,参数注解,变量注解

    /*** 注解* Java给我们提供了在运行时获取类的注解信息,可以得到类注解,方法注解,参数注解,变量注解。* 与上面获取方式一样,Java提供了2种获取方式,一种是获取全部的注解,返回一个数组,第二种是指定得到指定的注解。* 我们以一个类注解为例,讲解以下这两种获取方式。*///获取类上的注解Class clz = AnnotationObject.class;Annotation[] annotations = clz.getAnnotations();Annotation annotation = clz.getAnnotation(AnnotationObject.class);//根据注解进行后续处理for(Annotation ano:annotations){if(ano instanceof MyAnnotationFanshe){MyAnnotationFanshe annoFanshe=(MyAnnotationFanshe)ano;System.out.println(annoFanshe.name());System.out.println(annoFanshe.value());}}//获取参数上的注解Method method2 = clz.getMethod("doOtherThing",String.class);Class[] params = method2.getParameterTypes();Annotation[][] annotationInParam = method2.getParameterAnnotations();int i = 0;for (Annotation[] annos: annotationInParam){Class para = params[i++];for (Annotation anno : annotations){if(annotation instanceof MyAnnotationFanshe){MyAnnotationFanshe myAnnotation = (MyAnnotationFanshe) annotation;System.out.println("param: " + para.getName());System.out.println("name : " + myAnnotation.name());System.out.println("value :" + myAnnotation.value());}}}

7. 获取泛型

    /*** 泛型* 因为Java泛型是通过擦除来实现的,很难直接得到泛型具体的参数化类型的信息,* 但是我们可以通过一种间接的形式利用反射得到泛型信息。比如下面这个类:* 如果一个方法返回一个泛型类,我们可以通过method对象去调用getGenericReturnType来得到这个泛型类具体的参数化类型是什么。*/Class generObject = GenericObject.class;//反射得到返回类型为泛型类的方法Method method3 = generObject.getMethod("getLists");//调用getGenericReturnType得到方法返回类型中的参数化类型Type genericType = method3.getGenericReturnType();//判断该type对象能不能向下转型为ParameterizedTypeif(genericType instanceof ParameterizedType){//转型成功,调用getActualTypeArguments得到参数化类型的数组,因为有的泛型类,不只只有一个参数化类型如Map<K,V>ParameterizedType parameterizedType = ((ParameterizedType) genericType);//取出数组中的每一个的值,转型为Class对象输出Type[] types = parameterizedType.getActualTypeArguments();for (Type type : types){Class actualClz = ((Class) type);System.out.println("参数化类型为 : " + actualClz);}}//因为方法的参数为泛型类型的可能不止一个,所以通过getGenericParameterTypes得到是一个数组,//我们需要确定每一个元素,是否是具有参数化类型。后续的步骤与上面类似,就不多说了。//如果连方法参数都不带泛型类,那么只剩下最后一种情况,通过变量类型,即用Field类。例子如下:Field field1 = generObject.getField("lists");Type type = field1.getGenericType();if (type instanceof ParameterizedType){ParameterizedType parameterizedType = ((ParameterizedType) type);Type [] types = parameterizedType.getActualTypeArguments();for (Type type1 : types) {System.out.println("参数化类型 : " + ((Class) type1).getTypeName());}}

8. Java反射可以对数组进行操作

    /*** 数组* Java反射可以对数组进行操作,包括创建一个数组,访问数组中的值,以及得到一个数组的Class对象。* 下面,先说简单的,创建数组以及访问数组中的值:在反射中使用Array这个类,是reflect包下面的。*///创建一个int类型的数组,长度为3int[] intArray = (int[])Array.newInstance(int.class, 3);//通过反射形式给数组赋值for(int a=0;a<intArray.length;a++){Array.set(intArray, a, a+2);}//通过反射形式获取数组中的值for(int b=0;b<intArray.length;b++){Array.get(intArray, b);}//上述就是创建数组,访问数组中的值利用反射方式//对于得到一个数组的Class对象,简单的可以用int[].class,或者利用Class.forName的形式得到,写法比较奇怪Class clz2 = Class.forName("[I");System.out.println(clz2.getTypeName());//这个forName中的字符串,[表示是数组,I表示是int,float就是F,double就是D等等,如果要得到一个普通对象的数组Class stringClz = Class.forName("[Ljava.lang.String;");//[表示是数组,L的右边是类名,类型的右边是一个;;//这种方式获取数组的Class对象实在是太繁琐了。//在得到数组的Class对象之后,就可以调用他的一些独特的方法,比如调用getComponentType来得到数组成员的类型信息,如int数组就//是成员类型就是int。System.out.println(clz2.getComponentType().getTypeName());

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

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

相关文章

微型计算机主机箱内的所有部件均由大规模,2012年自考《计算机应用基础》模拟试题...

《计算机应用基础》模拟试题一、单选题 (每空1分&#xff0c;共30分)1. 在Word的编辑状态&#xff0c;当前在汉字输入状态&#xff0c;若要切换到输入大写英文字母状态&#xff0c;应当按( )。A.Caps Lock键 B.Shift键 C.Ctrl 空格键 D.Ctrl Shift键2. 一个完整的计算机系…

织梦自定义图片字段和缩略图一样_织梦图片集模型自定义图片字段调用

创建自定义函数打开/include/extend.func.php文件(注&#xff1a;这个文件就是系统预留的自定义函数接口文件&#xff0c;主要用于二次开发用的。如果你是老版本&#xff0c;默认没有这个文件&#xff0c;自己创建一个PHP文件即可)&#xff0c;在最下面的?>上一行加入以下函…

解释型语言和编译型语言的区别_从泛型的使用情况看出你对语言的理解程度(2)...

上篇我们提到&#xff1a;Java中的泛型是不可变的&#xff0c;可以通过<? extends E>实现了泛型的协变&#xff0c;<? super E>实现泛型的逆变。从泛型的使用情况看出你对语言的理解程度&#xff08;1&#xff09;今天我们来讲讲泛型单例工厂&#xff0c;在之前的…

泸州职业技术学院计算机单招试题,2021年泸州职业技术学院单招英语考试模拟试题库...

2021年高职单招升学一对一咨询高职单招郭老师:15683905627(微信)单招考试考什么单招专业技能考试文化统考;文化统考科目包括语文、数学、英语、专业综合理论。单招考试形式&#xff1a;专业技能考试文化统考。专业技能考试形式和内容由各专业大类联考委确定。文化统考科目为语文…

showdoc如何创建文件夹_showDoc生成文档

1. 创建项目2. 获取api_key和api_token1. 打开设置2. 获取api_key和token3. 生成文档1. 先cd进入你的项目目录&#xff0c;命令行模式下输入&#xff1a;wget https://www.showdoc.cc/script/showdoc_api.sh下载完毕&#xff0c;编辑vi showdoc_api.sh脚本内容的前面有两个变量…

win7下安装python失败问题_win7下安装ipython失败

关键就是报错啊大哥,没个报错信息你让我们怎么帮你,天眼通吗?请看:提问的艺术(中文版)在网络世界里&#xff0c;当提出一个技术问题时&#xff0c;你能得到怎样的回答&#xff1f;这取决于挖出答案的难度&#xff0c; 同样取决于你提问的方法。本指南旨在帮助你提高发问技巧&a…

职称计算机技巧集锦,2014职称计算机考试《Excel》使用技巧集锦(4)

四、 数据分析和管理技巧1. 管理加载宏Excel包括各种特殊作用的加载宏&#xff0c;它们使用自定义的函数、向导、对话框和其他工具&#xff0c;扩充了工作表的基本功能。默认情况下&#xff0c;每个加载宏都配置为在第一次使用时安装&#xff0c;也就是说在第一次需要某个加载宏…

map集合的putall_Map.put和Map.putAll方法之间的区别?

当使用putAll而不是put时&#xff0c;我看到巨大的性能优势。 请参见下面的示例程序&#xff1a;公共类SampleTest {public static void main(final String[] args) {final Map testMap new HashMap<>();final Map testMap2 new HashMap<>();final LocalDateTime…

ubuntu20.04自带python版本_替换 ubuntu 自带的python版本

首先在这里下载你想用的各个版本的python&#xff0c;我用的是2.7.11&#xff1a; https://www.python.org/ftp/python/还是老样子&#xff1a; ./configure --> make --> make install接下来将你自带的版本替换成自己的版本&#xff1a; 先 which python 查看你的p…

物料编码是计算机系统对物料,物料编码是什么?

物料编码是唯一标识物料的代码,通常用字符串(定长或不定长)或数字表示.物料编码是计算机系统对物料的惟一识别代码.它用一组代码来代表一种物料.物料编码必须是惟一的,也就是,一种物料不能有多个物料编码,一个物料编码不能有多种物料.目录简介意义原则方法注意事项处理特点展开…

python requests get post_python+requests进行get、post方法接口测试

简介&#xff1a;Requests 是用Python语言编写&#xff0c;基于 urllib&#xff0c;采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便&#xff0c;可以节约我们大量的工作&#xff0c;完全满足 HTTP 测试需求。Requests 的哲学是以 PEP 20 的习语为中心开发的&…

python中config命令_【Python】 配置解析ConfigParser 命令行参数解析optparser

ConfigParserConfigParser包装了配置文件的读取和写入&#xff0c;使得python程序可以更加轻松操作配置文件了。这里的配置文件是指.ini的那种文件&#xff0c;基本格式如下[section_a]a_key1a_value1a_key2a_value2[section_b]b_key1b_value1b_key2b_value2b_key3 b_value3将一…

sata接口测试软件,如何查看电脑是否支持USB 3.0?Hwinfo32检测SATA端口的方法

Hwinfo32检测SATA端口有很多效用&#xff0c;其中我们查看该SATA是否支持USB 3.0就是一个判断&#xff0c;更多的信息是为了了解SATA目前已经可使用的和在使用的端口情况&#xff0c;具体方法可以查看下文中的方法进行判断。Hwinfo32检测SATA端口的方法&#xff1a;1、直接下载…

python中deepcopy函数_Python学习笔记函数之copy()和deepcopy()

随笔记录方便自己和同路人查阅。#------------------------------------------------我是可耻的分割线-------------------------------------------在处理列表和字典时&#xff0c;尽管传递引用常常是最方便的方法&#xff0c;但如果函数修改了传入的列表或字典&#xff0c;你…

常规计算机 符号键是,电脑键盘上的字母和符号都表示什么

键盘上的键可以根据功能划分为几个组&#xff1a;键入(字母数字)键。这些键包括与传统打字机上相同的字母、数字、标点符号和符号键。控制键。这些键可单独使用或者与其他键组合使用来执行某些操作。最常用的控制键是 Ctrl、Alt、Windows 徽标键 和 Esc。功能键。功能键用于执行…

mfc try catch 捕获并显示_你的异常捕获够优雅不?求你别只会try{...} catch{...}了

文章来源 | cnblogs.com/jurendage/p/11255197.html作者 | 巨人大哥软件开发过程中&#xff0c;不可避免的是需要处理各种异常&#xff0c;就我自己来说&#xff0c;至少有一半以上的时间都是在处理各种异常情况&#xff0c;所以代码中就会出现大量的try {...} catch {...} fin…

vue 修改对象的值视图没有发生改变_在vue中处理对象属性改变视图不更新问题? - echart...

...图等等&#xff0c;但是这些代码比较难写&#xff0c;因此我们通常会用借助echarts&#xff0c;那你知道如何使用echarts吗&#xff1f;这篇文章就和大家讲讲echarts的使用方法&#xff0c;有一定的参考价值&#xff0c;感兴趣的朋友可以看看。以饼状图为例&#xff0c;介绍…

五年级计算机教材内容,五年级计算机教学计划

五年级计算机教学计划教育结构不断发生变革&#xff0c;现代教育和教学理论主张对教学计划的结构实行改革。下面是小编为您整理的关于五年级计算机教学计划的相关资料&#xff0c;欢迎阅读&#xff01;五年级计算机教学计划 范例1一、教材分析选用的教材是&#xff0c;浙江摄影…

linux添加用户命令_为Linux的cp和mv命令添加进度条

cp和mv可能是大家日常中使用最多的Linux命令之一。但是有一个突出的问题是这两个命令都不会有任何提示信息&#xff0c;这在操作大文件时候只能干等。可能大家对此已经习以为常&#xff0c;但是其实上也有解决解决方法&#xff0c;本文我们就介绍一个Gnu Coreutils(cp和mv的源代…

date time 分开存储如何合并_关于TDateTime的TDate与TTime合并的问题 | 菲菲的家

遇到TDate与TTime合并为TDateTime的问题&#xff0c;想想应该很容易&#xff0c;没想到发现一个百思不得其解的问题&#xff0c;在这里跟大家分享并求教。比如有两个组件DateTimePicker1和DateTimePicker2&#xff0c;Kind属性分别为dtkDate和dtkTime&#xff0c;一个用来定义T…