持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
这篇文章我们来说明一下Java 中的反射的概念。
什么是反射
我们有的时候会比较困惑于,为什么会有“反射”这个词的出现,“反射”在技术领域中,代表着什么?相比于“反射”,我们不妨先了解一下“正射”。
在我们日常开发中,我们在使用某个类,想声明其对应的实例对象的时候,就首先要确认这个类的定义。有了具体的类的定义之后,我们就可以直接对这个类进行实例化,实例化之后的对象,我们就可以拿来直接使用了。这种从类定义,到实例化类对象的过程就是“正射”,也就是说一个按照正常路子走的得到对象的流程。举例如下:
// 首先我们定义一个Chocolate 类
class Chocolate {
private String price;
private String color;
public void setPrice(String price) {
this.price = price;
}
public String getPrice() {
return price;
}
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
}
// 直接对这个类进行初始化,new 一个可以实际使用的对象,这个过程就是“正射”。
Chocolate chocolate = new Chocolate();
chocolate.setPrice("12.35");
chocolate.setColor("black");
接下来我们想一下“正射”的概念的反方向是什么,然后推导出“反射”的概念。
对于“正射”而言,是知道类定义 -> 得到类对象(使用new 关键字);对于反射而言,就是在最开始的时候,我们并不知道我要实例化的类的对象是什么,那么自然而然,我们也没有办法使用new 关键字来创建我们所需要的对象了。于是,Java 给出了“反射”的概念以及解决方案。
我们来看一下如何使用JDK 提供的反射API 进行反射调用实例化对象:
Class clz = Class.forName("com.xxx.xxx.Chocolate");
Method method = clz.getMethod("setPrice", String.class);
Constructor constructor = clz.getConstructor();
Object object = constructor.newInstance();
method.invoke(object, "12.35");
对于上面两段代码的执行结果,其最终得到的实际结果是完全一致的。但是我们明显可以发现,它们的实现思路是完全不一致的。对于第一段实例代码,还没有运行的时候就确定了要运行的类是什么,但是对于第二段代码则是在运行的时候是有字符串来获取要实际运行的类。
于是我们可以得到反射的概念:在运行的时候才能确定需要操作的类是什么,同时在运行的时候能获得类的完整构造,并可以调用对应的方法。
总结
这篇文章我们介绍了Java 中的反射的概念,并通过给出的两个例子来做实际的对比,来更好地帮助读者去理解。