深入理解Java中的反射机制和使用原理!详细解析invoke方法的执行和使用 (7)

invoke0方法是一个native方法,在HotSpot JVM里调用JVM_InvokeMethod函数:

JNIEXPORT jobject JNICALL Java_sun_reflect_NativeMethodAccessorImpl_invoke0 (JNIEnv *env, jclass unused, jobject m, jobject obj, jobjectArray args) { return JVM_InvokeMethod(env, m, obj, args); }

openjdk/hotspot/src/share/vm/prims/jvm.cpp:

JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)) JVMWrapper("JVM_InvokeMethod"); Handle method_handle; if (thread->stack_available((address) &method_handle) >= JVMInvokeMethodSlack) { method_handle = Handle(THREAD, JNIHandles::resolve(method)); Handle receiver(THREAD, JNIHandles::resolve(obj)); objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0))); oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL); jobject res = JNIHandles::make_local(env, result); if (JvmtiExport::should_post_vm_object_alloc()) { oop ret_type = java_lang_reflect_Method::return_type(method_handle()); assert(ret_type != NULL, "sanity check: ret_type oop must not be NULL!"); if (java_lang_Class::is_primitive(ret_type)) { // Only for primitive type vm allocates memory for java object. // See box() method. JvmtiExport::post_vm_object_alloc(JavaThread::current(), result); } } return res; } else { THROW_0(vmSymbols::java_lang_StackOverflowError()); } JVM_END

关键部分为Reflection::invoke_method: openjdk/hotspot/src/share/vm/runtime/reflection.cpp

oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) { oop mirror = java_lang_reflect_Method::clazz(method_mirror); int slot = java_lang_reflect_Method::slot(method_mirror); bool override = java_lang_reflect_Method::override(method_mirror) != 0; objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror))); oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror); BasicType rtype; if (java_lang_Class::is_primitive(return_type_mirror)) { rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL); } else { rtype = T_OBJECT; } instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror)); Method* m = klass->method_with_idnum(slot); if (m == NULL) { THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); } methodHandle method(THREAD, m); return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD); }

Java的对象模型 :klassoop

Java版的实现

JavaMethodAccessor的生成使用MethodAccessorGenerator实现

Generator for sun.reflect.MethodAccessor and sun.reflect.ConstructorAccessor objects using bytecodes to implement reflection. A java.lang.reflect.Method or java.lang.reflect.Constructor object can delegate its invoke or newInstance method to an accessor using native code or to one generated by this class. (Methods and Constructors were merged together in this class to ensure maximum code sharing.)

运用了asm动态生成字节码技术 - sun.reflect.ClassFileAssembler

invoke总结

invoke方法的过程:

在这里插入图片描述

MagicAccessorImpl:

原本Java的安全机制使得不同类之间不是任意信息都可见,但JDK里面专门设了个MagicAccessorImpl标记类开了个后门来允许不同类之间信息可以互相访问,由JVM管理

/** <P> MagicAccessorImpl (named for parity with FieldAccessorImpl and others, not because it actually implements an interface) is a marker class in the hierarchy. All subclasses of this class are "magically" granted access by the VM to otherwise inaccessible fields and methods of other classes. It is used to hold the code for dynamically-generated FieldAccessorImpl and MethodAccessorImpl subclasses. (Use of the word "unsafe" was avoided in this class's name to avoid confusion with {@link sun.misc.Unsafe}.) </P> <P> The bug fix for 4486457 also necessitated disabling verification for this class and all subclasses, as opposed to just SerializationConstructorAccessorImpl and subclasses, to avoid having to indicate to the VM which of these dynamically-generated stub classes were known to be able to pass the verifier. </P> <P> Do not change the name of this class without also changing the VM's code. </P> */ class MagicAccessorImpl { }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydsyj.html