JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
为了演示,我们定义一个用于测试的类:
public class ReflectObj
{
private int variable1;
public int variable2;
public static int variable3;
public static int variable4;
public ReflectObj()
{
System.out.println("invoke method ReflectObj()");
}
public ReflectObj(int var)
{
System.out.println("invoke method ReflectObj(int var)");
}
private ReflectObj(String var)
{
System.out.println("invoke method ReflectObj(String var)");
}
private void method1()
{
System.out.println("invoke method method1()");
}
private void method1(int var)
{
System.out.println("invoke method method1(int var)");
}
public void method2()
{
System.out.println("invoke method method2()");
}
public void method2(int var)
{
System.out.println("invoke method method2(int var)");
}
public static void method3()
{
System.out.println("invoke method method3()");
}
}
然后我们可以针对这个类编写测试反射效果的测试类:
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectTest
{
public static void main(String[] args) throws Exception
{
// 获得类的对象
Class<ReflectObj> clazz = ReflectObj.class;
// 获得ReflectObj的信息
System.out.println("ReflectObj的简单类名:" + clazz.getSimpleName());
// 实例化ReflectObj对象
ReflectObj obj1 = clazz.newInstance();
// 通过指定构造方法实例化对象
Constructor<ReflectObj> constructor1 = clazz
.getDeclaredConstructor(String.class);
// 因为构造方法是私有的,所以需要设置允许访问
constructor1.setAccessible(true);
ReflectObj obj2 = constructor1.newInstance("");
// 获得所有已定义字段
Field[] fields = clazz.getDeclaredFields();
if (fields != null)
{
for (Field field : fields)
{
System.out.println("name:" + field.getName() + " type:"
+ field.getType());
}
}
// 执行指定方法
Method method2 = clazz.getMethod("method2");
// 执行obj1的method2方法
method2.invoke(obj1);
// 执行静态方法
Method method3 = clazz.getMethod("method3");
method3.invoke(null);
}
}
反射机制在实际开发中是很实用的,但是相应的我们要牺牲一点执行效率,上述示例中仅介绍了反射中的部分方法,大家可以自己尝试写一下,多数方法的含义都是类似的。