反射————框架设计的灵魂
框架——半成品软件。可以在框架的基础上进行软件开发,简化代码。
反射——将类的各个组成部分封装为其他对象,这就是反射机制。
好处
1.可以在程序运行过程中,操作这些对象。
2.可以解耦,提高程序的可扩展性。
获取class对象的方式
1.Class.forName(“全类名”)——将字节码文件加载进内存,返回Class对象。
- 多用于配置文件,将类名定义在配置文件中,加载类。
2.类名.class——通过类名的属性class获取。
- 多用于参数的传递。
3.对象.getClass()——getClass()方法在Object类中定义着。
- 多用于对象的获取字节码方式。
结论
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取Class对象都是同一个。
Class对象功能
获取功能
1.获取成员变量们
-
Filed[ ] getFields()——获取所有public修饰的成员变量
-
Filed getField(String name)
-
Filed[ ] geDeclaredFields()——获取所有成员变量,不考虑修饰符
-
Filed 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()
Filed——成员变量
操作
1.设置值
- void set(Object obj,Object value)
2.获取值
- get(Object obj)
3.忽略访问权限修饰符的安全检查
- setAccessible(true)——暴力反射
Constructor——构造方法
创建对象 - T newInstance(Object …initargs)
如果使用空参数构造方法创建对象,操作可以简化——Class对象的newInstance方法。
method——方法对象
执行方法
- Object invoke(Object obj,Object…args)
获取方法名称 - string getName——获取方法名
反射——案例
需求——写一个“框架”,不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法。
实现
1.配置文件
2.反射
步骤
1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中。
2.在程序中加载读取配置文件。
3.使用反射技术来加载文件进内存。
4.创建对象。
5.执行方法。
package reflect;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
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 method = cls.getMethod(methodName);
//6.执行方法
method.invoke(obj);
}
}
package reflect;
public class Person {
public void eat(){
System.out.println("eat...");
}
}
className=reflect.Person
methodName=eat