反射
反射是框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
反射:将类的各个组成部分封装为其他对象,这就是反射机制
- 可以在程序运行过程中,操作这些对象。
- 可以解耦,提高程序的可扩展性。
Java代码的三个阶段
获取Class对象的方式
- Class.forname(“全类名”):将字节码文件加载进内存,返回class对象。
- 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
- 类名.class:通过类名的属性class获取
- 多用于参数的传递
- 对象.getclass():在Object类中定义
- 多用于对象的获取字节码的方式
- *注意:同一个字节码文件(.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的class对象都是同一个。**
1 | public class ReflectDemo { |
class对象功能
- 获取成员变量
- Field[] getfields() // 获取public修饰的成员变量
- Field[] getfields(String name) // 获取指定名称的public修饰的成员变量
- Field[] getDeclaredFields() // 获取所有的成员变量
- Field[] getDeclaredFields(String name) // 获取指定名称的成员变量
- 操作:可以设置set和获取值get
- 暴力反射:当访问非共有成员变量时,使用setAccessiable(true)忽略访问权限修饰符的安全检查
1 | public static void main(String[] args) throws Exception { |
- 获取构造方法
- Constructor<?>[] getConstructors()
- Constructor < T > getConstructor(类 <?> … parameterTypes) //
- Constructor<?>[] geDeclaredtConstructors()
- Constructor < T > getDeclaredConstructor(类 <?> … parameterTypes)
- 获取到构造方法来创建对象:T newInstance(Object … initargs)
1 | public static void main(String[] args) throws Exception { |
- 获取成员方法
- Method<?>[] getMethods()
- Method< T > getMethod(String name,类 <?> … parameterTypes)
- Method<?>[] geDeclaredtMethods()
- Method< T > getDeclaredMethodString name,(类 <?> … parameterTypes)
1 | public static void main(String[] args) throws Exception { |
- 获取类名
- String getname()
1 | System.out.println(personClass.getName()); //获取类名 |
案例
需求:写一个“框架”,可以帮我们创建任意类的对象,并且执行其中任意方法
实现
- 定义两个类
1
2
3
4
5
6
7
8
9
10public class Person {
public void eat(){
System.out.println("person eat");
}
}
public class Student {
public void sleep(){
System.out.println("Student sleep");
}
}- 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
1
2
3//配置文件为pro.properties
className=hxx.domain.Student //选择类
methodName=sleep //选择类中要执行的方法- 在程序中加载读取配置文件
- 使用反射技术来加载类文件
- 创建对象
- 执行方法
1 | public class ReflectTest { |