释义:Java的反射机制直白一点就是获取某个类里面的内容,包括字段、名称、构造函数、一般函数等,而要获取这些内容,只需要有这个类的对象即可。
场景:在反射技术出来之前,如果想要在一个已经编译完成并处在运行中的且该程序无法获取源代码的情况下实现扩展该程序的功能,那么只能通过多态的形式或者干脆无法扩展;而在有了反射技术之后,扩展就变得很简单,只需要在程序编写阶段预留接口和反射的程序,当程序编译完成处于运行中时,外部想要进行扩展,只需提供某个类的字节码文件并在相对应的配置文件中告诉程序具体哪个类即可,这样程序在启动时就会自动加载该字节码文件,达到扩展的目的。
示例:
★ 简单获取类对象,根据无参构造方法
Class<?> clazz = Class.forName("cn.test.clazz.Person"); //根据类名(需要加上包路径)获取类对象,常在配置文件中指定以达到扩展的目的
★ 根据有参构造方法获取类对象
Class<?> clazz = Class.forName("cn.test.clazz.Person"); //根据类名称获取类对象
Constructor<?> constructor = clazz.getConstructor(String.class, int.class); //根据指定有参构造函数的参数类型获取构造器对象
Object o = constructor.newInstance("张三", 23); //创建实例对象
★ 根据创建出来的实例获取属性
Class<?> clazz = Class.forName("cn.test.clazz.Person"); //根据类名称获取类对象
Field field = clazz.getDeclaredField("age"); //getDeclaredField能够获取"私有化"的字段
Field field2 = clazz.getField("age"); //getField获取"公有"的字段
field.setAccessible(true); //暴力破解(不建议)
Person person = (Person) clazz.newInstance(); //创建对象
field.set(person,23); //指定该字段是哪个对象里面的
int age = (int) field.get(person); //获取值,参数也是对象
★ 根据创建出来的实例获取方法
Class<?> clazz = Class.forName("cn.test.clazz.Person");
Method[] methods = clazz.getMethods(); //获取公有方法
Method[] declaredMethods = clazz.getDeclaredMethods(); //获取全部方法(包括私有)
Method method = clazz.getMethod("showTest", null); //指定调用具体方法, 无参时传null, 有参时传类对象
Object obj = clazz.newInstance(); //创建实例
Object invoke = method.invoke(obj, null); //执行方法
★ 结合配置文件扩展功能
FileInputStream fileInputStream = new FileInputStream(new File("<配置文件的位置>"));
Properties properties = new Properties();
properties.load(fileInputStream);
for (int i = 0; i < properties.size(); i++){
Object o = properties.get("<配置文件中的key>");
}
更多反射的功能请结合Java的API进行使用...