反射:将各类的各个组成部分封装为其它对象,这就是反射机制.
好处:
1.可以在程序运行过程中操作这些对象
2.可以解耦,提高程序的扩展性
Java代码在计算机中经历的阶段
获取class对象的方式:
1.class.forName("全类名"):将字节码文件加载进内存,返回class对象(静态方法),多用于配置文件,将类名定义在配置文件中,读取文件,加载类.
2.类名.class,通过类名的属性来进行class获取,多用于参数的传递(已经在内存中了)
3.对象.getclass(),这个方法在object类中定义,所有类继承object类,对用于对象获取字节码的方式.
结论:同一个字节码文件在一次程序运行中,只会被加载一次,无论通过哪一种方式进行获取的class,对象都是同一个.
Class对象的功能
获取功能:
1.获取成员变量们
Fieid getField(String name) 返回一个 Field对象,获取被public修饰的指定成员变量
Fieid[] getFields() 返回包含一个数组 ,获取被public修饰的所有的成员变量
Fieid getDeclaredField(String name) 返回一个 Field对象,获取指定的的成员变量
Fieid[] getDeclaredField()返回一个包含数组,获取所有的成员变量
2.获取构造方法
Constructor<>[] getConstructors() Constructor getConstructor(类<?>...parameterTypes) Constructor getDeclaredConstructor(类<?>...parameterTypes) Constructor[] getDeclaredConstructors()
3.获取成员方法们
Method[] getMethods() Method getMethod(String name,类<?>...parameterTypes) Method[] getDeclearedMethods() Method getDeclearedMethod(String name,类<?>...parameterTypes)
4.获取类名
String getName()
注意:获取不是被public修饰时,必须忽略访问权限修饰符的安全检查, setAccessible(true)暴力反射 默认为false.
Field:成员变量
操作:
1.设置值 void set(Object obj,Object value) 必须传入对象
2.获取值 get(Object obj)
Constructor:构造方法 构造方法的作用就是进行对象创建
创建对象: 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.IOException; 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创建properties对象 Properties pro = new Properties(); // 1.2加载配置文件,将其转化为一个集合 // 1.21获取文件的路径 ClassLoader classloader = reflectTest.class.getClassLoader();// 获取类加载器 InputStream is = classloader.getResourceAsStream("pro.properties");// 加载到内存中 pro.load(is);// 使properties转化为集合形式 // 2.获取配置文件的定义的数据 String className = pro.getProperty("className"); String methodName = pro.getProperty("methodName"); //3.加载该类进内存 Class personclass=Class.forName(className); //4.创建对象 Object obj=personclass.newInstance(); //5.获得方法 Method method=personclass.getDeclaredMethod(methodName); //6.执行方法 method.invoke(obj); } }
配置文件内容
Person类代码 package reflect; public class Person { public int age; private String name; public Person() { } public Person(int age,String name) { this.age=age; this.name=name; } public void eat() { System.out.println("吃饺子"); } }
执行结果
学习反思:Java是oop思想,而反射是对一些运行中程序的操控,通过类加载器以及io流对字节码文件进行内外存转换,在反射当中,成员变量、构造器以及方法都成为了对象,我们可以通过反射技术进行对其操控,做到万物皆对象这一思想.