Java反射机制的理解使用
一、Java反射机制的理解
反射(Reflection)是Java语言中的一项重要功能,通过反射API可以获取程序在运行时Java类的内部结构,实现对Java代码的动态操作,在实际项目开发中其多要用于框架的构建,一般开发中较少使用,但研究理解是非常必要的。
二、Java反射机制的使用
反射机制的实现主要依赖于Class类和java.lang.reflect.*包中提供的类。通过这些类可以实现对象的创建,类方法的访问等。
(一)Class对象的获取
Class类的构造方法为私有方法,只能由jvm虚拟机在运行时生成,用来保存实例对象的相关信息。获得一个实例对象对应的Class对象,主要有三种方法:
通过实例变量的getClass()方法,这种方法是获取效率最高和最安全的方式。
12Test test = new Test();Class cls = test.getClass();通过Class.forName()静态方法获取,这种方法是常用的一种方法,它通过输入的类名查找得到。
1Class t = Class.forName("java.lang.Thread");直接给出类文件的Class。
1Class cls = Test.class;
(二)Class对象的使用
构造方法的获取和使用
12345678910111213141516/** getConstructors可以获取声明为public的构造方法的集合,* getDeclaredConstructors()方法获取所有的构造方法集合*/Constructor[] constructors = cls.getConstructors();// 根据构造方法参数的类型获取对应的构造方法Constructor constructor = cls.getConstructor(String.class);for(Constructor con:constructors){// 构造方法的名称String name = con.getName();// 构造方法的参数类型Class[] type = con.getParameterTypes();}// 创建新的实例Object obj = constructor.newInstance();字段获取
1234567891011/** 获取public字段集合* getDeclaredFields()获取所有的字段*/Field[] fields = cls.getFields();// 字段名称String name = field.getName();// 字段类型Class type = field.getType();// 获取静态字段的值Object obj = field.get(Object);方法获取和执行
12345678910111213141516171819/** 获取该类的所有方法,包括父类的方法* getDeclaredMethods()获取该类的方法,不包括父类方法*/Method[] methods = cls.getMethods();// 方法返回值类型Class retType = method.getReturnType();// 方法名称String name = method.getName();// 方法类型String modifiers = Modifier.toString(method.getModifiers());// 方法参数类型Class[] paramTypes = method.getParameterTypes();/** 调用获取到的方法执行* one:对象的实例* two:方法参数的集合*/method.invoke(one,two);对类的私有域和方法的使用
类中的私有构造函数、方法和字段,通过相关的方法都可以获取到,但是在使用时确是禁止的,会抛出IllegalAccessException的异常。这是因为反射行为默认是受到Java访问的限制的,如果需要突破限制去访问控制,就需要调用Constructor、Method和Field的公共超类方法setAccessible(),设置为true时反射进制运行时会屏蔽Java语言的访问时检查。
在实际开发中,有时需要对隐藏的API进行使用时,通过这种机制就可以达到我们的目的。
反射机制的功能十分强大,在运行时可以获取类的结构,分析对象,调用任意的方法。但是由于反射的运行都是在运行时,在编译器会错过很多的检查,不规范的使用反射会提高程序的出错率。而且其运行时需要遍历搜寻的特点,使得使用反射执行方法的速度要慢于直接调用方法。所以一般情况下,应根据实际情况尽量减少使用反射。