十五.反射
(1)反射概述
Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。
Java反射机制提供的功能:
1.在运行时判断任意一个对象所属的类在运行时构造任意一个类的对象
2.在运行时判断任意一个类所具有的成员变量和方汽
3.在运行时获取泛型信息
4.在运行时调用任意一个对象的成员变量和方法>在运行时处理注解
5.生成动态代理
(2)获取Class实例
CLass的实例就对应着一个运行时类。
加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类。
获取实例方法:
(2)创建运行时类的对象
调用此方法(newInstance),创建对应运行时类(Person)的对象,内部调用了运行时类的空参构造器
要想此方法正常创建运行时类的对象,要求:
1.运行时类必须提供空参构造器
2.空参的构造器的访问权限得够,通常设置为public
(3)操作运行时类的指定属性
public void test2() throws Exception{
Class clazz = Person.class;
//创建运行时类的对象
Person p = (Person) clazz.newInstance();
//获取指定的属性,使用getDeclaredField方法,私有也可以获取
Field name = clazz.getDeclaredField("name");
//保证当前属性是可以访问的
name.setAccessible(true);
//获取和设置此对象的此属性值
name.set(p,"Tom");
System.out.println(name.get(p));
}
(4)操作运行时类的指定方法
public void test3() throws Exception{
Class clazz = Person.class;
//创建运行时类的对象
Person p = (Person) clazz.newInstance();
//获取指定对象的某个方法
//getDeclaredMethod():参数1:获取方法名;参数二:获取参数,以免重载不知道选哪个
Method show = clazz.getDeclaredMethod("show", String.class);
//保证当前方法是可以访问的
show.setAccessible(true);
//invoke:参数1:方法的调用者 参数2:给方法形参赋予的实参
//invoke()的返回值即为对应类中调用的方法的返回值
Object returnName = show.invoke(p, "ccw");
System.out.println(returnName);//获取到了返回值
System.out.println("*******************如何调用静态方法*************************");
Method eat = clazz.getDeclaredMethod("eat");
eat.setAccessible(true);
//如果方法没有返回值,则invoke()返回值为null
Object returnVal = eat.invoke(Person.class);
System.out.println(returnVal);//null
}