众所周知Java中有许多的框架供我们使用,而框架本身是一个半成品软件,我们可以框架的基础上进行开发,大大的简化了我们编码的工作量。
反射是框架设计的灵魂
在了解反射之前,我们先重温一下,我们熟知的Java代码在计算机中需要经历的三个阶段,源代码阶段、类对象阶段、运行阶段
我们编写完源代码之后,会经javac编译生成.class文件,
再经过Java虚拟机中的类加载器ClassLoader,生成class类对象,
然后再由类对象来创建实体对象。
反射:将类各个组成部分封装为class对象,这就是反射机制。如上图第一个
阶段到第二个阶段。
反射的作用:
1.可以在程序运行期间,对这些对象进行操作。
2.解耦,提高程序的可拓展性。
获取class对象的三种方式
1.在源代码阶段,用Class.forName(“全类名”),将字节码文件加载进内存,返回class对象.,常用于配置文件,将类名定义在配置文件中,读取文件,加载类.
2.在类对象阶段,类名.class:通过类名的属性class获取,多用于参数的传递
3.在运行阶段,对象.getClass():getClass()方法在object类中有定义,多用于对象的获取字节码的方式
且通过==比较发现,以上三种方式返回的class类对象地址是相同的,
结论:同一个字节码文件在一次程序运行过程中,只会被加载一次,不论通过哪一种哪一种方式获取的class对象都是同一个.
Class对象功能
1.获取成员变量
Field[] getFields():获取所有public修饰的成员变量
Field getFields(String name):获取public修饰的指定名字的成员变量
Field[] getDeclaredFields:获取所有成员变量
Field getDeclaredFields:获取指定名字的成员变量
获取的成员变量的用途:
设置值:void set(Object obj,Object value);
获取值:get(Object obj);
暴力反射:setAccessible(true);
2.获取构造方法
Constructor[] getConstructors():
Constructor[] getConstructors(类<?>… parameterTypes):
Constructor[] getDeclaredConstructors()
Constructor[] getDeclaredConstructors(类<?>… parameterTypes)
3.获取成员方法
Method[] getMethods();
Method[] getMethods(String name,类<?>… parameterTypes);
Method[] getDeclaredMethods();
Method[] getDeclaredMethods(String name,类<?>… parameterTypes);
4.获取类名
String getName();
案列
需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法,
实现:
1.配置文件
2.反射
步骤:
1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中,
2.在程序中加载读取配置文件
3.使用反射方法来加载类文件进内存
4.创建对象
5.执行方法
框架类
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* 框架类
*/
public class Construct {
public static void main(String[] args) throws Exception {
//1.加载配置文件
//1.1创建properties对象
Properties pro = new Properties();
//1.2加载配置文件,转换成集合
//1.2.1获取class目录下的配置文件
ClassLoader classLoader = Construct.class.getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties");
pro.load(resourceAsStream);
//2.获取配置文件中定义的数据
String className = pro.getProperty("className");
String methodName = pro.getProperty("methodName");
//3.加载该类进内存
Class<?> aClass = Class.forName(className);
//4.创建对象
Object o = aClass.newInstance();
//5.获取方法对象
Method method = aClass.getMethod(methodName);
//6.执行方法
method.invoke(o);
}
}
pro.properties
className = cn.javaweb.refectdemo.Person
methodName = eat