在Java运行时环境中,对于任意一个类,可以知道这个类的属性和方法,实例化对象,而通过实例化的对象获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。那么反射可以实现什么功能呢?
1、在运行时判断任意一个对象所属的类。
2、在运行时构造任意一个类的对象。
3、在运行时判断任意一个类所具有的成员变量和方法。
4、在运行时调用任意一个对象的方法。
其中,一般而言,开发者社群说到的动态语言,大致认同的一个定义是:"程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。"从这个观点看,Perl,Python,Ruby是动态语言,而C++,Java,C#不是动态语言。
Java程序可以加载一个运行时才得知名称的class,获悉其完整构造,并生成其对象实体或对其fields设值或唤起其methods。这种可以"看透class"的能力被称为introspection(内省、内观、反省)。Reflection是Java被视为动态(或者准动态)语言的一个关键性质。
在JDK中,主要由以下类来实现Java反射机制,而这些类都位于java.lang.reflect包中:
Class类:代表一个类,是Reflection API中的核心类。
Field类:代表类的属性。
Method类:代表类的方法。
Constructor类:代表类的构造方法。
Array类:提供了动态创建数组以及访问数组元素的静态方法。
在java.lang.Object类中定义了getClass()方法,因此对于任意一个Java对象都可以通过此方法获得对象的类型。
Class类方法:
getName():获取类的完整名字。
getFields():获取类中public类型的属性。
getDeclaredFields():获取类的所有属性。
getMethods():获取类中所有public类型的方法。
getDeclareMethods():获取类的所有方法。
getConstructors():获取类public类型的构造方法。
getMethod(String name,Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
Field类方法:
get(Object obj):获取obj中当前属性的值。
set(Object obj,Object value):设置obj中当前属性的值为value。
另外,Field类还提供了getXXX()方法族及setXXX()方法族,用于操纵基本数据类型。
上个例子:
Method类用于操作类的方法。其中Method类的invoke(Object obj,Object args[])方法接收的参数必须为对象,如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,如果实际被 调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,再将其返回。
例子: