1.反射:框架的设计的灵魂
框架:半成品软件。
可以在框架的基础上进行软件开发,简化代码
反射:将类的各个组成部分封装为其他对象,这就是反射机制
- 好处:
1.在运行过程中,操作 Class 里面的对象
2.可以解耦,可以提高程序的可扩展性
java 代码在计算机中经历的三个阶段
源代码阶段:字节码文件
类对象阶段:把字节码文件加载进内存
2.Class 对象功能:
获取Class对象的方式:
- Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
多用于配置文件,将类名定义在配置文件中,读取文件,加载类
Class cls1 = Class.forName("cn.itcast.domain.Person");
- 类名.class:通过类名的属性class获取
多用于参数的传递
Class cls2 = Person.class;
- 对象.getClass():getClass()方法在Object类中定义着。
多用于获取对象的字节码方式
Person p = new Person();
Class cls3 = p.getClass();
结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的 Class 对象都是同一个
获取功能:
1.获取成员变量们
- Field [] getFields(): 获取所有的 public 修饰的成员变量
- Field [] getFields( String name):获取指定名称的 public 修饰的成员变量
- Field[] getDeclaredFields()
- Field getDeclaredField(String name)
2. 获取构造方法们
- Constructor<?>[] getConstructors()
- Constructor<T> getConstructor(类<?>... parameterTypes)
- Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
- Constructor<?>[] getDeclaredConstructors()
3. 获取成员方法们
* Method[] getMethods()
* Method getMethod(String name, 类<?>... parameterTypes)
* Method[] getDeclaredMethods()
* Method getDeclaredMethod(String name, 类<?>... parameterTypes)
4. 获取类名
* String getName()
详解:
1.Field 成员变量
操作:
1.设置值
Field a = personClass.getField("a");
//获取成员变量a 的值
Person p = new Person();
Object value = a.get(p);
System.out.println(value);
//设置a的值
a.set(p, "张三");
System.out.println(p);
2.获取值
Field a = personClass.getField("a");
//获取成员变量a 的值
Person p = new Person();
Object value = a.get(p);
System.out.println(value);
3.忽略访问权限修饰符的安全检查
Field d = personClass.getDeclaredField("d");
//忽略访问权限修饰符的安全检查
d.setAccessible(true);//暴力反射
Object value2 = d.get(p);
System.out.println(value2);
2.构造方法
1.获取构造函数
Constructor constructor = personClass.getConstructor(String.class, int.class);
System.out.println(constructor);
// 结果:public cn.itcast.domain.Person(java.lang.String,int)
Constructor constructor1 = personClass.getConstructor();
System.out.println(constructor1);
// 结果:public cn.itcast.domain.Person()
2.给构造函数设置值
Object person = constructor.newInstance("张三", 23);
System.out.println(person);
//结果:Person{name='张三', age=23, a='null', b='null', c='null', d='null'}
3.创建对象
Object person1 = constructor1.newInstance();
System.out.println(person1);
//结果:Person{name='null', age=0, a='null', b='null', c='null', d='null'}
3.成员方法
获取指定名称的方法
//获取指定名称的方法
Method eat_method = personClass.getMethod("eat");
Person p = new Person();
//执行方法
eat_method.invoke(p);
//结果:eat...
获取重载的方法 eat
Method eat_method1 = personClass.getMethod("eat", String.class);
eat_method1.invoke(p, "food");
//结果:eat...food
4..获取类名
String className = personClass.getName();
System.out.println(className);
//结果:cn.itcast.domain.Person
3.反射小案例
可以创建任意类的对象,可以执行任意类的方法
1.创建 file 文件 pro.properties
className=cn.itcast.domain.Person
methodName=eat
2.Refletest.java
//加载配置文件
//创建 Properties 对象
Properties pro = new Properties();
//加载配置文件,转换为一个集合
ClassLoader classLoader = Refletest.class.getClassLoader();
//获取 class 目录下的配置文件
InputStream is = classLoader.getResourceAsStream("pro.properties");
pro.load(is);
//获取配置文件中定义的数据
String className = pro.getProperty("className");
String methodName = pro.getProperty("methodName");
//3.加载该类进内存
Class cls = Class.forName(className);
//4.创建对象
Object obj = cls.newInstance();
//5.获取方法对象
Method method = cls.getMethod(methodName);
//6.执行方法
method.invoke(obj);
结果:
image.png更改 pro.properties 为:
className=cn.itcast.domain.Student
methodName=sleep
结果:
image.png总结:要执行某个类的某个方法,只需要更改 配置文件 pro.properties 即可
网友评论