反射是框架设计的灵魂。将类的各个组成部分封装为其他对象,这就是反射机制。运行程序的时候,我们实际上加载的是class文件。是由"类加载器"将class文件加载进内存。class文件进入到内存中,字节码文件对象,就是由 Class 类来描述这个字节码文件对象的。字节码文件对象是一个大的概念,是class文件被加载进内存中形成的。那么一个类中,还有成员变量,构造方法,成员方法。我们又用三个不同的类,分别去描述成员变量,构造方法,成员方法。
如何获取class文件对象?
Class.forName("全类名")
类名.class
对象.getClass():getClass()
如何获取class文件对象中的成员变量并对其进行赋值?
Field[] getFields()
: 获取所有public修饰的成员变量
Field getField(String name)
: 获取指定名称的 public修饰的成员变量
Field[] getDeclaredFields()
: 获取所有的成员变量,不考虑修饰符
Field getDeclaredField(String name)
: 获取指定的成员变量,不考虑修饰符
//获得到这个类的字节码文件对象
Class cls = Class.forName("com.itheima.demo1.Student");
//通过字节码文件的整体来获取其中某一个成员变量
Field name = cls.getDeclaredField("name");
//暴力反射。
name.setAccessible(true);
//设置值,获取值。
Student s = new Student();
name.set(s,"张三");
Object o = name.get(s);
System.out.println(o);
如何获取class文件对象中的构造方法并创建这个类的对象?
Constructor<?>[] getConstructors()
: 获得所有public修饰的构造方法Constructor<T> getConstructor(参数类型.class)
: 获得public修饰的指定构造Constructor<T> getDeclaredConstructor(参数类型.class)
: 获取所有构造方法,无视修饰符Constructor<?>[] getDeclaredConstructors()
: 获得指定构造,无视修饰符
//通过有参构造来创建对象
Class cls1 = Class.forName("com.itheima.demo1.Student");
Constructor constructor = cls1.getConstructor(String.class, int.class);
Object o1 = constructor.newInstance("张三", 23);
System.out.println(o1);
//通过无参构造来创建对象
Class cls2 = Class.forName("com.itheima.demo1.Student");
Constructor constructor2 = cls2.getConstructor();
Object o2 = constructor2.newInstance();
System.out.println(o2);
//简化写:直接通过字节码文件对象获取无参构造
Class cl3 = Class.forName("com.itheima.demo1.Student");
Object o3 = cls3.newInstance();
System.out.println(o3);
如何获取class文件对象中的成员方法并进行调用?
Method[] getMethods()
: 获得所有public修饰的成员方法Method getMethod(方法名, 参数类型.class)
:获得public修饰的指定成员方法Method[] getDeclaredMethods()
: 获取所有成员方法,无视修饰符Method getDeclaredMethod(方法名, 参数类型.class)
: 获得指定成员方法,无视修饰符
Class cls = Class.forName("com.itheima.demo1.Student");
Method method = cls.getDeclaredMethod("eat");
Student s = new Student();
method.invoke(s);
示例:
class Demo{
public static void main(String [] args){
//1.加载配置文件
//1.1创建Properties对象
Properties pro = new Properties();
//1.2加载配置文件,转换为一个集合
//1.2.1获取class目录下的配置文件]
ClassLoader classLoader = 当前类名.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("pro.properties");//当前配置文件在src目录下
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);
}
}