Java教程

反射

本文主要是介绍反射,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

反射

用来动态的操纵Java代码

反射机制的主要作用:

  • 在运行时分析类的能力
  • 在运行时查看对象
  • 实现通用的数组操作代码
  • 利用Method对象

Class类

在Java程序运行时,系统为所有的对象维护一个被称为运行时类型标识。这个标识存放了一个类运行时的类型信息。在编译时,一个类对应一个Class对象,相同类型的对个实例对象会对应同一个Class对象。

获得Class类型实例的三种方式

  • 实例对象.getClass()
  • Class.forName("类名") //类名应该包含其包的路径
  • 类.class

注意:Class对象实际上表示的是一种类型,并不仅仅指类。int不是类,但int.class是一个Class类的对象

基本类型有Class对象,数组有Class对象,连关键字void也有Class对象

可以说Class类是对类型的抽象和集合

newInstance()

可以动态地创建一个类的实例

对象.getClass().newInstance()

newInstance()方法会调用默认的构造函数,如果没有默认构造函数则会抛出异常

如果想使用带参构造函数,需要用到Constructor类的newInstance方法,Constructor对象可以使用Class的实例获取,在下面讲

利用反射分析类的能力

主要是用java.lang.reflect包中的三个类,分别用于描述类的域、方法、构造器

  • Field
  • Method
  • Constructor

Field类

int getModifiers()		//获取修饰限定符的编号,使用Modifier.toString()静态方法将编号装换为对应字符串
Class getType() 		//获取域的类型
String getName()		//获取域的名称

Method类

int getModifiers()		//获取修饰限定符的编号
Class getReturnType()		//获取返回值类型对象
String getName()		//获得方法的名称
Class[] getParameterTypes()	//获得参数类型对象数组

Constructor类

int getModifiers()		//获取修饰限定符的编号
String getName()		//获得构造函数的名称
Class[] getParameterTypes()	//获得参数类型对象数组

三种类对象的获取

使用Class类中的方法获得Field类、Method类、Constructor类

Field[] getFields()			      //获取本类和父类的全部公有域
Method[] getMethods()			      //获取本类和从父类继承的全部公有方法
Constructor[] getConstructors()		      //获取类中的全部公有构造函数
Field[] getDeclaredFields()		      //获取类中的全部域,不包括父类的
Method[] getDeclaredMethods()		      //获取类中的全部方法,不包括父类的
Constructor[] getDeclaredConstructors()	      //获取类中的全部构造函数,不包括父类的

在运行时使用反射分析对象

可以使用反射机制进一步查看数据域的实际内容。

查看数据与内容的关键方法是Field类中的get方法。f为一个Field类型的对象,obj是包含f域的类的实例,那么f.get(obj)将返回obj对象中f域的实际数据。

Employee jack = new Employee("jack", 35000, 10, 1, 1998); // name money month day year
Class cl = jack.getClass();
Field f = cl.getDeclaredField("name");
Object ob = f.get(jack);	                          //如果是基本类型则会自动装箱

如果name域为private时,上面的代码会抛出IllegalAccessExecption异常,因为反射机制默认情况下受限于Java的访问控制,但是我们可以跳过安全管理器的控制,只需要调用Field、Method或Constructor对象的setAccessible(boolean)方法,将其设为true,则Field、Method或Constructor对象就可以跳过安全管理器的控制

调用任意方法

反射机制允许调用任意方法,使用Method类的invoke()方法。其使用方法与Field类的get()方法类似

Object invoke(Object obj, Object... args)

第一个参数为执行方法的对象:m为一个Method类的对象,obj是包含m方法的类的实例

其余参数为调用m方法的参数列表

我们首先要获取一个指定的Method对象才能够执行invoke()方法,那一个指定的Method对象如何获取呢,可以有以下两种方法:

  • 对getDeclareMethod方法返回的集合进行遍历,找到指定的方法
  • 使用getMethod方法,通过传入方法名和所有的参数类型即可获得一个指定的方法
Student st = new Student("张三");

Class cl = st.getClass();

//获得Student类的getName()方法的对象
Method get = cl.getMethod("getName");
//获得Student类的setName(String)方法的对象
Method set = cl.getMethod("setName", String.class);

//调用invoke执行相关的方法
String name1 = (String)get.invoke(st);
set.invoke(st, "李四");
String name2 = (String)get.invoke(st);
//name1:张三	name2:李四
这篇关于反射的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!