反射:框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
反射:将类的各个组成部分封装为其他对象,这就是反射机制
好处:
1. 可以在程序运行过程中操作这些对象
2. 可以解耦,提高程序的可扩展性
Class对象功能:
获取功能:
1. 获取成员变量
-
Field[] getFileds():获取所有public修饰的成员变量
-
Field getField(String name)获取指定名称的public修饰的成员变量
-
Field[] getDeclaredFields()获取所有成员变量,不考虑修饰符
-
Field getDeclaredFields(String name)
操作:
-
设置值void set(Object obj,Object value)
-
获取值get(Object obj)
-
忽略访问权限修饰符的安全检查setAccessible(true):暴力反射
2.获取构造方法
-
Constructor<?>[] getConstructor()
-
Constructor getConstructor(类<?>…parameterTypers)
-
Constructor getDeclaredConstructor(类<?>…parameterTypers)
-
Constructor<?> getDeclaredConstructor()
操作:
-
创建对象:T newInstance(Object…initargs)
-
如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
Class personClass=Person.class;
Constructor constructor=personClass.getConstructor(String.class,int.class);
System.out.println(constructor);
//创建对象
Object person=constructor.newInstance("张三",23);
System.out.println(person);
3 .获取成员方法
-
Method[] getMethods()
-
Method getMethod(String name,类<?>…parameterTypers)
-
Method[] getDeclaredMethods()
-
Method getDeclaredMethods(String name,类<?>…parameterTypers)
操作:
-
执行方法:Object invoke(Object obj,Object…args)
-
获取方法名称:String getName
4.获取类名
String getName()
Java代码在计算机中经历的阶段:三个阶段
1. Source源代码阶段
2. Class类对象阶段
3. Runtime运行时阶段–》创建对象
获取Class对象的方式
1. 第一个阶段:Class.forName(“全类名”);(多用于配置文件,将类名定义在配置文件中。读取文件,加载类)
2. 第二个阶段:通过类名的属性class获取(多用于参数的传递 )
3. 第三个阶段:对象.getClass():getClass()方法在Object类中定义着(多用于对象的获取字节码方式)
//1.
Class cls1=Class.forName("cn.itcast.domain.Person");
System.out.println(cls1);
//2.
Class cls2=Person.class;
System.out.println(cls2);
//3.
Person p=new Person();
Class cls3=p.getClass();
System.out.println(cls3);
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个
案例:
需求:写一个“框架”,可以帮我们创建任意类的对象,并且执行其中任意方法
实现:
1. 配置文件
2. 反射
步骤:
1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2. 在程序中加载读取配置文件
3. 使用反射技术来加载类文件进内存
4. 创建对象
5. 执行方法
//配置文件pro.properties
className=cn.itcast.domain.Student
methodName=sleep
public class ReflectTest {
public static void main(String[] args) throws Exception{
//1.加载配置文件
//1.1创建Properties对象
Properties pro=new Properties();
//1.2加载配置文件,转换为一个集合
//1.2.1获取class目录下的配置文件
ClassLoader classLoader=ReflectTest.class.getClassLoader();
InputStream is=classLoader.getResourceAsStream("pro.properties");
pro.load(is);
//2.获取配置文件中定义的数据
String className=pro.getProperty("className");
String methodName=pro.getProperty("methodName");
//3.加载该类进内存
Class cls=Class.forName(className);
//4.创建对象
Object obj=cls.newInstance();
//5.获取方法对象
Method m=cls.getMethod(methodName);
//6.执行方法
m.invoke(obj);
}
}