本文以个人学习认知为主,如有雷同,纯属不巧和(滑稽)
- 问题要求:写一个简单的“框架”,可以创建任意类的对象,实现类中的任意方法。
在平时java学习中,创建任意类只需new相关类名即可,而如果我们需要封装这一步骤,使其解耦与模块化,具有可拓展性。这个问题乍一看似乎无从下手,但其实在接触了Java反射特性之后,我们就能一步步解决问题。
首先,让我们来认识一下,什么是java的反射特性?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
在java代码运行过程中,字节码文件(*.class)通过类加载器,将类的各个组成部分封装为其他对象(即Class对象!),并加载到内存中,这一过程即体现了反射机制。
如果我们获得了Class对象,我们就可以对类中相关的成员变量、成员方法以及构造方法进行动态的操作,是不是对问题的要求有点思路了?
让我们通过实际代码来进一步演示,首先创建一个示例person类
public class person {
//创建私有成员变量
private int age;
private String name;
//创建空参构造函数
public person() {
}
//创建成员方法
public void method(){
System.out.println("该方法被调用!");
}
}
然后,在同一个包下,创建一个File配置文件,里面存储相关配置信息
//我的person类在reflect的包下,注意需要写全类名,即路径+类名
className=reflect.person
methodName=method
最后创建一个Reflect类,实现简单的框架
public class test {
public static void main(String[] args) throws Exception {
//创建一个properties对象,用于读取配置文件
Properties pro=new Properties();
//通过类加载器寻找并获得配置文件的输入字节流
ClassLoader classLoader = test.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("pro.properties");
//从输入字节流中读取属性列表
pro.load(is);
//获取配置信息
String className = pro.getProperty("className");
String methodName = pro.getProperty("methodName");
//创建className的Class对象
Class cls = Class.forName(className);
//获取Class对象的构造方法并实例化
Object o = cls.getDeclaredConstructor().newInstance();
//获取成员方法
Method method = cls.getMethod(methodName);
//调用实例化对象o中的成员方法
method.invoke(o);
}
}
运行代码,我们可以看到控制台输出
person类是我们写的一个示例类,我们同样可以创建其他的类,我们只需要修改配置文件中的className与methodName,就可以创建任意类的对象,实现类中的任意方法,成功了完成了问题要求,并对反射有了一点初步的了解(这也就是为什么说反射机制是java框架的灵魂!)
ps.如果有一起学习上手Java框架的朋友,欢迎私信!