一、反射是什么?
能够分析类能力的程序称为反射(reflective)。
反射机制可以用来: 在运行时分析类的能力(名称、类型)、在运行时查看对象(值)、实现通用的数组操作代码、利用 Method 对象。
二、Class类
在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。 这个信息跟踪着每个对象所属的类,保存这些信息的类被称为 Class。虚拟机利用运行时类型信息选择相应的方法执行。
获取Class对象的三种方法:
⑴Object 类中的 getClass( ) 方法将会返回一个 Class 类型的实例。
⑵Class.forName(类名或接口名)调用静态方法 forName 获得类名对应的 Class 对象,最常用。
⑶如果 T 是任意的 Java类型(或 void关键字), T.class 将代表匹配的类对象。
三、利用反射分析类
在java.lang.reflect 包中有三个类 Field、Method 和 Constructor 分别用于描述类的属性、方法和构造器。
⑴ java.lang.Class
String getName()返回类的名字。如果类在一个包里,包的名字也作为类名的一部分
Class getSuperclass()返回父类Class
Object newlnstance() 动态地创建一个类的实例
①Field getField(String name) 返回指定名称的公有域
Field getDeclaredField(String name)返回类中声明的给定名称的域
Field[] getFields()
Filed[] getDeclaredFields()
getFields 方法将返回一个包含 Field 对象的数组,这些对象记录了这个类或其超类的公有域。getDeclaredField方法也将返回包含Field对象的数组, 这些对象记录了这个类的全部域。如果类中没有域,或者Class对象描述的是基本类型或数组类型,这些方法将返回一个长度为0的数组。
②Method getDeclaredMethod("方法名",参数类型.class,……)获得特定的方法
Method[] getMethods()
Method[] getDeclareMethods()
返回包含 Method 对象的数组:getMethods将返回所有的公有方法,包括从超类继承来的公有方法;getDeclaredMethods 返回这个类或接口的全部方法, 但不包括由超类继承了的方法。
③Constructor getDeclaredConstructor(参数类型.class,……)获取特定的构造方法
Constructor[] getConstructors()
Constructor[] getDeclaredConstructors()
返回包含 Constructor 对象的数组,其中包含了Class对象所描述的类的所有公有构造器(getConstructors) 或所有构造器(getDeclaredConstructors)。
⑵ java.lang.reflect.Field java.lang.reflect.Method java.lang.reflect.Constructor
Class getDeclaringClass( ) 返冋一个用于描述类中定义的构造器、方法或域的 Class 对象。
int getModifiers( ) 返回一个用于描述构造器、方法或域的修饰符的整型数值。使用 Modifier 类中的静态方法可以分析这个返回值。
String getName( ) 返冋一个用于描述构造器、 方法或域名的字符串。
Class[] getExceptionTypes( ) (在 Constructor 和 Method 类中) 返回一个用于描述方法抛出的异常类型的 Class 对象数组。
Class[] getParameterTypes( ) (在 Constructor 和 Method 类中) 返回一个用于描述参数类型的 Class 对象数组。
Class getType( )(在Field类中)返回描述域所属类型的 Class 对象
Class getReturnType( ) (在 Method 类中) 返回一个用于描述返回类型的 Class 对象。
public Object invoke(Object implicitParameter,Object[] explicitParamenters) (在 Method 类中)调用这个对象所描述的方法, 传递给定参数,并返回方法的返回值。对于静态方法, 把 null 作为隐式参数传递。在使用包装器传递基本类型的值时,基本类型的返回值必须是未包装的。
Object newlnstance(Object[] args) (在 Constructor类中)构造一个这个构造器所属类的新实例。
⑶ java.lang.reflect.Modifier
static String toString(int modifiers) 返回对应modifiers中的位设置的修饰符的字符串表示。
static boolean is修饰符(int modifiers)这些方法将检测方法名中对应的修饰符在 modffiers 值中的位
四、查看对象域
查看对象域的关键方法是 Field类中的 get 方法。如果 f 是一个 Field类型的对象,obj 是某个包含 f 域的类的对象,f.get(obj) 将返回一个对象,其值为 obj 域的当前值。调用 f.set(obj,value) 可以将 obj 对象的 f 域设置成新值。
反射机制的默认行为受限于 Java 的访问控制。要想全部可以访问,需要调用 Field、Method 或 Constructor 对象的 setAccessible()方法。
java.lang.reflect.AccessibleObject
void setAccessible(boolean flag) 为反射对象设置可访问标志。flag 为 true 表明屏蔽 Java语言的访问检查,使得对象的 私有属性也可以被査询和设置 。
boolean isAccessible( ) 返回反射对象的可访问标志的值。
static void setAccessible(AccessibleObject[ ] array,boolean flag) 是一种设置对象数组可访问标志的快捷方法。
五、使用反射编写泛型数组
使用 Class 类(只能定义表示数组的类对象)的 getComponentType方法确定数组对应的类型。
java.lang.reflect.Array
static Object get(Object array,int index)
static xxx getXxx(Object array,int index)( xxx 是 boolean、byte、 char、 double、 float、int、 long、 short 之中的一种基本类型。)
这些方法将返回存储在给定位置上的给定数组的内容。
static void set(Object array,int index,Object newValue)
static setXxx(Object array,int index,xxx newValue)
这些方法将一个新值存储到给定位置上的给定数组中。
static int getLength(Object array) 返回数组的长度。
static Object newInstance(Class componentType,int length)
static Object newInstance(Class componentType,int[]lengths)
返回一个具有给定类型、 给定维数的新数组。