在java学习中,我们经常提到动态代理,也知道动态代理是依靠反射来实现的。这几天也一直在看反射的知识,从基础开始学习反射。反射,就如光的反射一样,经过镜子之前都是正向的,而反射出去的就是我们要学习的反射。个人理解就是从终点回推的逆向学习。
Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性和方法。反射是
Java 被视为动态(或准动态)语言的关键,允许程序于执行期 Reflection APIs 取得任何已知名称之 class 的內部信息
反射中有几个相关的API
java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造方法
在有反射之前,我们创建一个类的对象,并调用其中的方法、属性都是如下代码:
public void test(){
Person p = new Person();
p.setAge(10);
p.setName("lihegang");
System.out.println(p);
}
这是我们平常调用的方式,先实例化对象,然后调用方法。现在通过反射可以创建一个类的对向,并调用其中的结构:
public void test(){
Class clazz = Person.class;
1.//创建clazz对应的运行类Person类的对象
Person p =(Person)clazz.newInstance();
Field f1 =clazz.getField("name");
f1.set(p,"LiuDeHua"); // 将f1即是name属性,对应p对象name为LiuDeHua
2.private私有属性获取
Field f2 =clazz.getDeclaredField("age"); //获取属性
f2.setAccessible(true); // 设置可访问
f2.set(p,20);
3.通过反射调用运行时类的指定方法
Method m1 =clazz.getMethod("show");
m1.invoke(p) //invoke意思是调用,p调用m1
Method m2 =clazz.getMethod("display",String.class);
m2.invoke(p,"CHN");
}
这里用到了刚才提到的API中的Class,Class clazz = Person.class意思是将类进行实例化,实例化类后进行实例化对象即可调用反射。
简单的反射即是上面代码中的三步:
1.声明类的实例,并创建运行时类的对象;
2.对属性的设置:先获取属性名,然后设置属性。属性有private和public等修饰符修饰,如果是private修饰,那么获取该属性需调用getDeclareField()方法,参数为属性名,设置setAccessible为true。
3.对方法的调用:先获取方法名,然后调用方法。通过getMethod("show")获取方法,参数名为方法名。同person.show()相反,反射是获取show的方法名后,进行逆向的调用,通过invoke()方法来进行调用方法。
由于对动态代理只是知道怎么用,不了解反射的整体知识。因此这几天在看反射的知识,从最基础的开始,学习一下, 也是高校期间的课余所学吧。