我是靠谱客的博主 高挑薯片,最近开发中收集的这篇文章主要介绍java底层调用_深入分析Java反射(七)-简述反射调用的底层实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前提

Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行Debug。

本文主要介绍反射调用的底层实现,当然还没有能力分析JVM的实现,这里只分析到最终Native方法的调用点。底层会依赖到Unsafe类,可以的话可以看下笔者之前写的一篇文章《神奇的魔法类和双刃剑-Unsafe》。

反射调用的底层实现探究

主要考虑下面的情况:

属性操作:java.lang.reflect.Field#set(Object obj, Object value)和java.lang.reflect.Field#get(Object obj)。

构造器调用:java.lang.reflect.Constructor#newInstance(Object ... initargs)。

方法调用:java.lang.reflect.Method#invoke(Object obj, Object... args)。

处理属性操作的底层实现

属性操作方法Field#set(Object obj, Object value)和Field#get(Object obj)底层都是委托到jdk.internal.reflect.FieldAccessor实现:

public interface FieldAccessor {

/** Matches specification in {@link java.lang.reflect.Field} */

public Object get(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public boolean getBoolean(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public byte getByte(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public char getChar(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public short getShort(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public int getInt(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public long getLong(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public float getFloat(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public double getDouble(Object obj) throws IllegalArgumentException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void set(Object obj, Object value)

throws IllegalArgumentException, IllegalAccessException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void setBoolean(Object obj, boolean z)

throws IllegalArgumentException, IllegalAccessException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void setByte(Object obj, byte b)

throws IllegalArgumentException, IllegalAccessException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void setChar(Object obj, char c)

throws IllegalArgumentException, IllegalAccessException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void setShort(Object obj, short s)

throws IllegalArgumentException, IllegalAccessException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void setInt(Object obj, int i)

throws IllegalArgumentException, IllegalAccessException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void setLong(Object obj, long l)

throws IllegalArgumentException, IllegalAccessException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void setFloat(Object obj, float f)

throws IllegalArgumentException, IllegalAccessException;

/** Matches specification in {@link java.lang.reflect.Field} */

public void setDouble(Object obj, double d)

throws IllegalArgumentException, IllegalAccessException;

}

FieldAccessor接口有很多的实现,FieldAccessor接口实例是通过jdk.internal.reflect.ReflectionFactory这个工厂构造的:

public FieldAccessor newFieldAccessor(Field field, boolean override) {

checkInitted();

Field root = langReflectAccess.getRoot(field);

if (root != null) {

// FieldAccessor will use the root unless the modifiers have

// been overrridden

if (root.getModifiers() == field.getModifiers() || !override) {

field = root;

}

}

return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);

}

最终委托到UnsafeFieldAccessorFactory#newFieldAccessor():

class UnsafeFieldAccessorFactory {

static FieldAccessor newFieldAccessor(Field field, boolean override) {

Class> type = field.getType();

boolean isStatic = Modifier.isStatic(field.getModifiers());

boolean isFinal = Modifier.isFinal(field.getModifiers());

boolean isVolatile = Modifier.isVolatile(field.getModifiers());

boolean isQualified = isFinal || isVolatile;

boolean isReadOnly = isFinal && (isStatic || !override);

if (isStatic) {

// This code path does not guarantee that the field's

// declaring class has been initialized, but it must be

// before performing reflective operations.

UnsafeFieldAccessorImpl.unsafe.ensureClassInitialized(field.getDeclaringClass());

if (!isQualified) {

if (type == Boolean.TYPE) {

return new UnsafeStaticBooleanFieldAccessorImpl(field);

} else if (type == Byte.TYPE) {

return new UnsafeStaticByteFieldAccessorImpl(field);

} else if (type == Short.TYPE) {

return new UnsafeStaticShortFieldAccessorImpl(field);

} else if (type == Character.TYPE) {

return new UnsafeStaticCharacterFieldAccessorImpl(field);

} else if (type == Integer.TYPE) {

return new UnsafeStaticIntegerFieldAccessorImpl(field);

} else if (type == Long.TYPE) {

return new UnsafeStaticLongFieldAccessorImpl(field);

} else if (type == Float.TYPE) {

return new UnsafeStaticFloatFieldAccessorImpl(field);

} else if (type == Double.TYPE) {

return new UnsafeStaticDoubleFieldAccessorImpl(field);

} else {

return new UnsafeStaticObjectFieldAccessorImpl(field);

}

} else {

if (type == Boolean.TYPE) {

return new UnsafeQualifiedStaticBooleanFieldAccessorImpl(field, isReadOnly);

} else if (type == Byte.TYPE) {

return new UnsafeQualifiedStaticByteFieldAccessorImpl(field, isReadOnly);

} else if (type == Short.TYPE) {

return new UnsafeQualifiedStaticShortFieldAccessorImpl(field, isReadOnly);

} else if (type == Character.TYPE) {

return new UnsafeQualifiedStaticCharacterFieldAccessorImpl(field, isReadOnly);

} else if (type == Integer.TYPE) {

return new UnsafeQualifiedStaticIntegerFieldAccessorImpl(field, isReadOnly);

} else if (type == Long.TYPE) {

return new UnsafeQualifiedStaticLongFieldAccessorImpl(field, isReadOnly);

} else if (type == Float.TYPE) {

return new UnsafeQualifiedStaticFloatFieldAccessorImpl(field, isReadOnly);

} else if (type == Double.TYPE) {

return new UnsafeQualifiedStaticDoubleFieldAccessorImpl(field, isReadOnly);

} else {

return new UnsafeQualifiedStaticObjectFieldAccessorImpl(field, isReadOnly);

}

}

} else {

if (!isQualified) {

if (type == Boolean.TYPE) {

return new UnsafeBooleanFieldAccessorImpl(field);

} else if (type == Byte.TYPE) {

return new UnsafeByteFieldAccessorImpl(field);

} else if (type == Short.TYPE) {

return new UnsafeShortFieldAccessorImpl(field);

} else if (type == Character.TYPE) {

return new UnsafeCharacterFieldAccessorImpl(field);

} else if (type == Integer.TYPE) {

return new UnsafeIntegerFieldAccessorImpl(field);

} else if (type == Long.TYPE) {

return new UnsafeLongFieldAccessorImpl(field);

} else if (type == Float.TYPE) {

return new UnsafeFloatFieldAccessorImpl(field);

} else if (type == Double.TYPE) {

return new UnsafeDoubleFieldAccessorImpl(field);

} else {

return new UnsafeObjectFieldAccessorImpl(field);

}

} else {

if (type == Boolean.TYPE) {

return new UnsafeQualifiedBooleanFieldAccessorImpl(field, isReadOnly);

} else if (type == Byte.TYPE) {

return new UnsafeQualifiedByteFieldAccessorImpl(field, isReadOnly);

} else if (type == Short.TYPE) {

return new UnsafeQualifiedShortFieldAccessorImpl(field, isReadOnly);

} else if (type == Character.TYPE) {

return new UnsafeQualifiedCharacterFieldAccessorImpl(field, isReadOnly);

} else if (type == Integer.TYPE) {

return new UnsafeQualifiedIntegerFieldAccessorImpl(field, isReadOnly);

} else if (type == Long.TYPE) {

return new UnsafeQualifiedLongFieldAccessorImpl(field, isReadOnly);

} else if (type == Float.TYPE) {

return new UnsafeQualifiedFloatFieldAccessorImpl(field, isReadOnly);

} else if (type == Double.TYPE) {

return new UnsafeQualifiedDoubleFieldAccessorImpl(field, isReadOnly);

} else {

return new UnsafeQualifiedObjectFieldAccessorImpl(field, isReadOnly);

}

}

}

}

}

这里注意一下属性修饰符的判断:

isStatic:静态属性,也就是static关键字修饰的属性。

isFinal:final关键字修饰的属性。

isVolatile:valatile关键字修饰的属性。

isQualified:valatile关键字或者final关键字修饰的属性。

isReadOnly:是否只读属性,final关键字修饰的属性或者static关键字修饰并且不能覆盖(override = false)的属性。

通过上面修饰符做判断,得到最终的FieldAccessor实现。这里挑一个例子进行分析,例如一个普通非静态没有volatile和final关键字修饰属性最终就会得到UnsafeObjectFieldAccessorImpl的实例:

class UnsafeObjectFieldAccessorImpl extends UnsafeFieldAccessorImpl {

UnsafeObjectFieldAccessorImpl(Field field) {

super(field);

}

public Object get(Object obj) throws IllegalArgumentException {

ensureObj(obj);

return unsafe.getObject(obj, fieldOffset);

}

public void set(Object obj, Object value)

throws IllegalArgumentException, IllegalAccessException{

ensureObj(obj);

if (isFinal) {

throwFinalFieldIllegalAccessException(value);

}

if (value != null) {

if (!field.getType().isAssignableFrom(value.getClass())) {

throwSetIllegalArgumentException(value);

}

}

unsafe.putObject(obj, fieldOffset, value);

}

public boolean getBoolean(Object obj) throws IllegalArgumentException {

throw newGetBooleanIllegalArgumentException();

}

public byte getByte(Object obj) throws IllegalArgumentException {

throw newGetByteIllegalArgumentException();

}

// 省略其他直接抛出异常的方法

}

可见UnsafeObjectFieldAccessorImpl中除了get(Object obj)和set(Object obj, Object value)方法,其他方法都是直接抛出IllegalArgumentException。而get(Object obj)和set(Object obj, Object value)底层分别依赖于jdk.internal.misc.Unsafe的putObject(obj, fieldOffset, value)和getObject(obj, fieldOffset)方法。而属性的内存偏移地址是在UnsafeObjectFieldAccessorImpl的父类UnsafeFieldAccessorImpl的构造函数中计算出来的:

abstract class UnsafeFieldAccessorImpl extends FieldAccessorImpl {

static final Unsafe unsafe = Unsafe.getUnsafe();

protected final Field field;

protected final long fieldOffset;

protected final boolean isFinal;

UnsafeFieldAccessorImpl(Field field) {

this.field = field;

if (Modifier.isStatic(field.getModifiers()))

fieldOffset = unsafe.staticFieldOffset(field);

else

fieldOffset = unsafe.objectFieldOffset(field);

isFinal = Modifier.isFinal(field.getModifiers());

}

// 省略其他方法

}

这里可以做个小结,属性反射操作Field的setXX和getXX方法最终委托到jdk.internal.misc.Unsafe的putXX和getXX方法,而属性的内存偏移地址是通过jdk.internal.misc.Unsafe的staticFieldBase()、staticFieldOffset和objectFieldOffset几个方法计算的。

处理构造器调用的底层实现

Constructor#newInstance()方法调用依赖到ConstructorAccessor:

public T newInstance(Object ... initargs)

throws InstantiationException, IllegalAccessException,

IllegalArgumentException, InvocationTargetException

{

if (!override) {

Class> caller = Reflection.getCallerClass();

checkAccess(caller, clazz, clazz, modifiers);

}

if ((clazz.getModifiers() & Modifier.ENUM) != 0)

throw new IllegalArgumentException("Cannot reflectively create enum objects");

ConstructorAccessor ca = constructorAccessor; // read volatile

if (ca == null) {

ca = acquireConstructorAccessor();

}

@SuppressWarnings("unchecked")

T inst = (T) ca.newInstance(initargs);

return inst;

}

// ConstructorAccessor接口

public interface ConstructorAccessor {

/** Matches specification in {@link java.lang.reflect.Constructor} */

public Object newInstance(Object[] args)

throws InstantiationException,

IllegalArgumentException,

InvocationTargetException;

}

而获取ConstructorAccessor实例也是通过反射工厂类ReflectionFactory,具体是ReflectionFactory#newConstructorAccessor:

public ConstructorAccessor newConstructorAccessor(Constructor> c) {

checkInitted();

Class> declaringClass = c.getDeclaringClass();

// 抽象方法会进入此if分支

if (Modifier.isAbstract(declaringClass.getModifiers())) {

return new InstantiationExceptionConstructorAccessorImpl(null);

}

// 宿主类直接是Class类型,则无法实例化

if (declaringClass == Class.class) {

return new InstantiationExceptionConstructorAccessorImpl

("Can not instantiate java.lang.Class");

}

// use the root Constructor that will not cache caller class

Constructor> root = langReflectAccess.getRoot(c);

if (root != null) {

c = root;

}

// 当前声明构造的宿主类是ConstructorAccessorImpl的子类

if (Reflection.isSubclassOf(declaringClass,

ConstructorAccessorImpl.class)) {

return new BootstrapConstructorAccessorImpl(c);

}

//

if (noInflation && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {

return new MethodAccessorGenerator().

generateConstructor(c.getDeclaringClass(),

c.getParameterTypes(),

c.getExceptionTypes(),

c.getModifiers());

} else {

NativeConstructorAccessorImpl acc =

new NativeConstructorAccessorImpl(c);

DelegatingConstructorAccessorImpl res =

new DelegatingConstructorAccessorImpl(acc);

acc.setParent(res);

return res;

}

}

可见最终得到的ConstructorAccessor实例为DelegatingConstructorAccessorImpl,而DelegatingConstructorAccessorImpl只是一个委托实现,底层是调用NativeConstructorAccessorImpl:

class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {

private final Constructor> c;

private DelegatingConstructorAccessorImpl parent;

private int numInvocations;

NativeConstructorAccessorImpl(Constructor> c) {

this.c = c;

}

public Object newInstance(Object[] args)

throws InstantiationException,

IllegalArgumentException,

InvocationTargetException

{

// We can't inflate a constructor belonging to a vm-anonymous class

// because that kind of class can't be referred to by name, hence can't

// be found from the generated bytecode.

if (++numInvocations > ReflectionFactory.inflationThreshold()

&& !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {

ConstructorAccessorImpl acc = (ConstructorAccessorImpl)

new MethodAccessorGenerator().

generateConstructor(c.getDeclaringClass(),

c.getParameterTypes(),

c.getExceptionTypes(),

c.getModifiers());

parent.setDelegate(acc);

}

return newInstance0(c, args);

}

void setParent(DelegatingConstructorAccessorImpl parent) {

this.parent = parent;

}

// 这个就是最终构造实例化对象的native方法

private static native Object newInstance0(Constructor> c, Object[] args)

throws InstantiationException,

IllegalArgumentException,

InvocationTargetException;

}

NativeConstructorAccessorImpl#newInstance0()就是最终构造实例化对象的Native方法。当然有例外的情况,例如非正常调用下,如果构造器的宿主类是一个抽象类,那么最终会返回一个InstantiationExceptionConstructorAccessorImpl实例,里面直接抛出InstantiationException异常。

处理方法调用的底层实现

Method#invoke()调用依赖于MethodAccessor:

// MethodAccessor接口

public interface MethodAccessor {

/** Matches specification in {@link java.lang.reflect.Method} */

public Object invoke(Object obj, Object[] args)

throws IllegalArgumentException, InvocationTargetException;

}

public Object invoke(Object obj, Object... args)

throws IllegalAccessException, IllegalArgumentException,

InvocationTargetException{

if (!override) {

Class> caller = Reflection.getCallerClass();

checkAccess(caller, clazz,

Modifier.isStatic(modifiers) ? null : obj.getClass(),

modifiers);

}

MethodAccessor ma = methodAccessor; // read volatile

if (ma == null) {

ma = acquireMethodAccessor();

}

return ma.invoke(obj, args);

}

获取MethodAccessor实例的逻辑和前两节类似,是通过ReflectionFactory#newMethodAccessor():

public MethodAccessor newMethodAccessor(Method method) {

checkInitted();

if (Reflection.isCallerSensitive(method)) {

Method altMethod = findMethodForReflection(method);

if (altMethod != null) {

method = altMethod;

}

}

// use the root Method that will not cache caller class

Method root = langReflectAccess.getRoot(method);

if (root != null) {

method = root;

}

if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {

return new MethodAccessorGenerator().

generateMethod(method.getDeclaringClass(),

method.getName(),

method.getParameterTypes(),

method.getReturnType(),

method.getExceptionTypes(),

method.getModifiers());

} else {

NativeMethodAccessorImpl acc =

new NativeMethodAccessorImpl(method);

DelegatingMethodAccessorImpl res =

new DelegatingMethodAccessorImpl(acc);

acc.setParent(res);

return res;

}

}

最终会委托到NativeMethodAccessorImpl#invoke(Object obj, Object[] args):

class NativeMethodAccessorImpl extends MethodAccessorImpl {

private final Method method;

private DelegatingMethodAccessorImpl parent;

private int numInvocations;

NativeMethodAccessorImpl(Method method) {

this.method = method;

}

public Object invoke(Object obj, Object[] args)

throws IllegalArgumentException, InvocationTargetException

{

// We can't inflate methods belonging to vm-anonymous classes because

// that kind of class can't be referred to by name, hence can't be

// found from the generated bytecode.

if (++numInvocations > ReflectionFactory.inflationThreshold()

&& !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {

MethodAccessorImpl acc = (MethodAccessorImpl)

new MethodAccessorGenerator().

generateMethod(method.getDeclaringClass(),

method.getName(),

method.getParameterTypes(),

method.getReturnType(),

method.getExceptionTypes(),

method.getModifiers());

parent.setDelegate(acc);

}

return invoke0(method, obj, args);

}

void setParent(DelegatingMethodAccessorImpl parent) {

this.parent = parent;

}

private static native Object invoke0(Method m, Object obj, Object[] args);

}

而NativeMethodAccessorImpl#invoke0()就是方法调用的最终调用的Native方法。

小结

学习知识过程总是阶梯式上升的,JDK中的类库设计也类似这样,如果提前熟悉Unsafe类的相关方法,其实反射调用的底层实现也能够相对轻易地理解。属性、构造和方法反射调用底层的实现(只考虑正常调用的情况下)如下:

对于属性(Field):Field#setXX()和Field#getXX()分别对应Unsafe的putXX()和getXX()方法,也就是说完全依赖Unsafe中的Native方法。

对于构造(Constructor):Constructor#newInstance()底层调用NativeConstructorAccessorImpl#newInstance0()。

对于方法(Method):Method#invoke()底层调用NativeMethodAccessorImpl#invoke0()

个人博客

(本文完 e-a-20181216 c-1-d)

技术公众号(《Throwable文摘》),不定期推送笔者原创技术文章(绝不抄袭或者转载):

娱乐公众号(《天天沙雕》),甄选奇趣沙雕图文和视频不定期推送,缓解生活工作压力:

最后

以上就是高挑薯片为你收集整理的java底层调用_深入分析Java反射(七)-简述反射调用的底层实现的全部内容,希望文章能够帮你解决java底层调用_深入分析Java反射(七)-简述反射调用的底层实现所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部