黑马程序员技术交流社区

标题: 【武汉校区】Java反射机制 [打印本页]

作者: 武汉分校-小舞    时间: 2019-3-12 16:56
标题: 【武汉校区】Java反射机制
Java反射机制
Java的反射机制可以通过字节码获取到一个类的的各个组成部分。一个类的组成主要就是【构造方法】【成员变量】【成员方法】等,而这每一个组成部分都可以用对象来表示。
为了方便理解,我画了一张图。我们可以把Java的反射机制看做是一个照妖镜,它可以让类的字节码Class现出原形。

在Java的世界里万物阶对象,类本身和类的组成部分都是对象,分别有对应的类,如下

获取字节码
要去做反射的操作,首先第一步需要获取类的字节码,获取字节码有三种方式。
1. 类名.class
Class cls1=Student.class;
Class cls2=String.class;
Class cls3=int.class;


2. Class.forName("包名.类名")
Class cls1=Class.forName("com.itheima.Student");

3. 对象.getClass()
Student stu=new Student();
Class cls1=stu.getClass();
注意:不管用那种方式获取字节码,只要类相同,字节码就是同一个
Class表示类的字节码,在Class类中提供了和反射相关的方法,这些方法的命名其实是很有规律,掌握了这些规律
学习反射其实挺简单的。
Xxx表示Field、Method、Constructor
1. getXxx 获取公有的
2. getDeclaredXxx 获取私有的

获取公有的类成员
1. 反射获取构造方法(Constructor)
//获取一个构造方法
Constructor getConstructor(Class...cls)
//获取多个构造方法
Constructor[] getConstructors();

2. 反射获取成员变量(Field)
//获取一个成员变量
Field getField(String name)
//获取多个成员变量
Field[] getFields()

3. 反射获取成员方法(Method)
//获取一个成员方法
Method getMethod(String methodname,Class...cls)
//获取多个成员方法
Method[] getMethods()


获取私有的类成员
1. 反射获取构造方法(Constructor)
//获取一个构造方法
Constructor getDeclaredConstructor(Class...cls)
//获取多个构造方法
Constructor[] getDeclaredConstructors();

2. 反射获取成员变量(Field)
//获取一个成员变量
Field getDeclaredField(String name)
//获取多个成员变量
Field[] getDeclaredFields()

3. 反射获取成员方法(Method)
//获取一个成员方法
Method getDeclaredMethod(String methodname,Class...cls)
//获取多个成员方法
Method[] getDeclaredMethods()

反射的应用
反射一般在写框架的时候用的比较多,框架可以理解为完成某些需求的半成品,也就是说主要的代码结构已经写好了,使用框架时是只需要按照它的要求添加一些配置、一些类完成你特殊的需求。
但是这里有一个问题,如果框架是你写的,别人使用你的框架,扔给你一个具体类怎么和你的框架结合到一起跑起来呢?
如有下面一个需求:给任意JavaBean的任意属性赋值,写一个小的框架
public class MyBeanUtils{
public static void setProperty(Object bean,String name,Object value){
//获取字节码
Class clazz=bean.getClass();
//获取属性名为name的成员变量,用变量f表示
Field f=clazz.getDeclaredField(name);
//暴力反射:取消权限检查
f.setAccessible(true);
//给属性赋值
f.set(bean,value);
}
}
就上面简单的一个类,就可以给任意JavaBean对象的任意属性赋值,不管对象中有那些属性。

Student s=new Student();
//给Student对象的name和age属性赋值
MyBeanUtils.setProperty(s,"name","张三");
MyBeanUtils.setProperty(s,"age","18");
Phone p=new Phone();
//给Phone对象的brand和price属性赋值
MyBeanUtils.setProperty(p,"brand","华为");
MyBeanUtils.setProperty(s,"price","2000");

总结
反射可以通过字节码获取字节码类的各个组成部分。获取到构造方法Constructor可以用来创建对象;获取到成员变量Field可以用来给变量赋值或者获取值;获取到方法Method可以让方法执行。

反射一般是用来写框架的,需要用到什么样的类,类中有那些方法,框架的使用肯定是有规则的,按照规则利用反射进行调用,等你把完成具体功能的类写好了框架就能把你的类加载进来按照预先的规则运行。












欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2