之前学习Java基础的时候,反射内容却是匆匆掠过,如今却要反哺。
开篇,反射的机制是什么?将类的各个组成部分封装为其他对象。那它的好处是什么?可以解耦,提高程序的可扩展性。这里提到了解耦,便想到了框架,配置文件,XML,properties等等。
话不多说,直接上案例:写一个“框架”在不能改变类的任何代码的前提下,可以帮我们创建任意类的对象,并执行其中任意方法。
思考:正常情况下创建对象就是 类名 对象名 =new 类名(); 执行其方法则是 对象名.方法名();那用反射该如何实现以上功能呢?
步骤:
1、创建对象的全类名(className)和需要执行的方法(methodName)定义在配置文件(pro.properties)中
2、在main方法中加载读取配置文件(pro.properties)中
3、使用反射加载类文件进内存
4、使用反射创建对象
5、使用反射执行方法
干起来!
1、在src目录下创建pro.properties
className=day1.pageReflect.Worker //类名 day1.pageReflect.Student
methodName=goWork //方法名 goSchool
2、创建两个类Student和Work类
Student.java
package day1.pageReflect;
public class Student {
String name;//姓名
int age;//年龄
public void goSchool(){
System.out.println("上学去");
}
}
Work.java
package day1.pageReflect;
public class Worker {
String num;//工号
String sex;//性别
public void goWork(){
System.out.println("上班去");
}
}
3、创建 ReflectTest类
ReflectTest.java
package day1.pageReflect;
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、创建properties对象对象
Properties pro=new Properties();
//2.加载配置文件
//2.运动IO流获取class目录下配置文件位置
ClassLoader classLoader = ReflectTest.class.getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties");
pro.load(resourceAsStream);//此处会产生一个异常,将其抛出
//3.获取配置文件中定义的数据
String className= pro.getProperty("className");
String methodName=pro.getProperty("methodName");
//4.用反射将该类塞进内存
Class cls=Class.forName(className);
//5.用反射创建其对象
Object obj=cls.newInstance();
//6.用反射获取方法对象
Method method=cls.getMethod(methodName);
//执行方法
method.invoke(obj);
}
}
4、运行结果
当pro.properties里边className指向Stduent,MethodName指向goSchool时运行ReflectTest
当pro.properties里边className指向Work,MethodName指向goWork时运行ReflectTest
5、总结
在反射技术的支持下,我们不需要繁琐地创建类对象,调用类方法等步骤使用该类,如此我们可以在程序运行的过程中,操作这些对象并且提高了程序的扩展性。