前言
在上篇 Java 反射机制(一) 介绍了一些 Java
反射相关的常用 API ,在知道了如何去使用反射之后,作为一个合格的工程师,下一步肯定是要去了解它的如何实现的,我们今天就来看看在 JDK
源码中是如何去实现反射的(PS:以下源码分析基于 JDK1.8
)。
Field 类 set 方法的实现
Field
类的 set
方法是在运行时用来动态修改一个类的属性的值,进入到 Field
类的 set
方法的源码如下:
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, obj, modifiers);
}
}
getFieldAccessor(obj).set(obj, value);
}
首先根据 override
判断是否需要检查字段的访问权限,然后通过 getFieldAccessor
方法获得一个 FieldAccessor
字段访问者对象,最后调用的是 FieldAccessor
类的 set
方法进行下一步操作的,FieldAccessor
是一个接口,定义了对字段的一些操作,该接口有如下一些实现类:
要看 set
到底调用的是哪个实现类的方法,那么我们需要看看 getFieldAccessor()
返回的是哪个类的对象,下面是 getFieldAccessor
方法的源码实现:
// security check is done before calling this method
private FieldAccessor getFieldAccessor(Object obj)
throws IllegalAccessException
{
boolean ov = override;
FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
return (a != null) ? a : acquireFieldAccessor(ov);
}
这里先通过 override
来获取不同的缓存的 FieldAccessor
,其中 overrideFieldAccessor
代表本类覆盖父类的字段访问者对象缓存,fieldAccessor
是本类的字段访问器对象缓存。如果缓存存在的话就直接复用之前的对象,否则就调用 Field
类的 acquireFieldAccessor
方法获取。我们进入到 acquireFieldAccessor
方法中看看,方法源码如下:
private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) {
// First check to see if one has been created yet, and take it
// if so
FieldAccessor tmp = null;
if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck);
if (tmp != null) {
if (overrideFinalCheck)
overrideFieldAccessor = tmp;
else
fieldAccessor = tmp;
} else {
// Otherwise fabricate one and propagate it up to the root
tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
setFieldAccessor(tmp,