最近看了看反射,反射涉及的知识还是很广的,这里我们只是简单的了解一下。
反射机制
首先我们来了解一下反射的原理。
具体参考https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html,这篇博文是我认为最容易让人理解反射的一篇博文了。
首先有“反”,就有“正”,什么是正?
构建一个Apple
类,包含了price
属性:
public class Apple {
private int price;
public Apple() {
}
public Apple(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Apple{" +
"price=" + price +
'}';
}
}
正常来说,我们是使用 new
关键字初始化一个对象,我们称为“正射”:
Apple apple = new Apple();
问题来了,如果我们不知道一开始要初始化的类对象是什么的话怎么办?
//1、获取类的 Class 对象实例
Class clz = Class.forName("com.zhudan.reflex.Apple");
//2、根据 Class 对象实例获取 Constructor 对象
Constructor appleConstructor = clz.getConstructor();
//3、使用 Constructor 对象的 newInstance 方法获取反射类对象
Object appleObj = appleConstructor.newInstance();
那我们应该如何调用这个类对象的方法呢?
//1、获取方法的 Method 对象
Method setPriceMethod = clz.getMethod("setPrice", int.class);
//2、利用 invoke 方法调用方法
setPriceMethod.invoke(appleObj, 5);
//同理
Method getPriceMethod = clz.getMethod("getPrice");
getPriceMethod.invoke(appleObj);
//同理
Method toStringMethod = clz.getMethod("toString");
System.out.println(toStringMethod.invoke(appleObj));
进一步的,我自己写了一个构造函数,用过构造函数给属性赋值,该怎么做?
//获取Constructor的时候加上参数的类型,反射创造的时候赋值
Class clzNew = Class.forName("com.zhudan.reflex.Apple");
Constructor appleConstructorNew = clzNew.getConstructor(int.class);
Object appleObjNew = appleConstructorNew.newInstance(14);
Method toStringMethodNew = clz.getMethod("toString");
System.out.println(toStringMethodNew.invoke(appleObjNew));
有人问了,为什么要用反射实例化对象,什么场景会用到反射机制呢?
反射是为了增加程序的灵活性。
有可能创建对象的程序比要创建的对象先开发好,比如插件程序。
还可能是要在运行期从配置文件读取类名,这时候就没有办法硬编码。