通过反射创建实例的用法是:
Class<?> clz = Class.forName("com.xx.xx");
Constructor<?> constructor = clz.getConstructor(String.Class);
Object obj = constructor.newInstance("xx");
通过
Class.forName
在上一篇ART的反射调用(一)中已经分析
一. Class.getConstructor
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
return getConstructor0(parameterTypes, Member.PUBLIC);
}
private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
int which) throws NoSuchMethodException{
if (parameterTypes == null) {
parameterTypes = EmptyArray.CLASS;
}
for (Class<?> c : parameterTypes) {
if (c == null) {
throw new NoSuchMethodException("parameter type is null");
}
}
//核心调用
Constructor<T> result = getDeclaredConstructorInternal(parameterTypes);
if (result == null || which == Member.PUBLIC && !Modifier.isPublic(result.getAccessFlags())) {
throw new NoSuchMethodException("<init> " + Arrays.toString(parameterTypes));
}
return result;
}
private native Constructor<T> getDeclaredConstructorInternal(Class<?>[] args);
1.1 getDeclaredConstructorInternal
getDeclaredConstructorInternal
的实现在/art/runtime/native/java_lang_Class.cc
中
static jobject Class_getDeclaredConstructorInternal(
JNIEnv* env, jobject javaThis, jobjectArray args) {
ScopedFastNativeObjectAccess soa(env);
//核心调用,[1.2]
mirror::Constructor* result = mirror::Class::GetDeclaredConstructorInternal(
soa.Self(),
//将Java层的Class对象转换为mirror::Class指针
DecodeClass(soa, javaThis),
//将Java层的数组转换为存放mirror::Class指针的数组
soa.Decode<mirror::ObjectArray<mirror::Class>*>(args));
return soa.AddLocalReference<jobject>(result);
}
1.2 mirror::Class::GetDeclaredConstructorInternal
GetDeclaredConstructorInternal
声明在/art/runtime/mirror/class.h
template <bool kTransactionActive = false>
static Constructor* GetDeclaredConstructorInternal(Thread* self,
mirror::Class* klass,
mirror::ObjectArray<mirror::Class>* args)
SHARED_REQUIRES(Locks::mutator_lock_);
NOTE:kTransactionActive默认为false
这个方法的实现在/art/runtime/mirror/class.cc
template <bool kTransactionActive>
mirror::Constructor* Class::GetDeclaredConstructorInternal(
Thread* self,
mirror::Class* klass,
mirror::ObjectArray<mirror::Class>* args) {
StackHandleScope<1> hs(self);
//kTransactionActive默认为false
const size_t pointer_size = kTransactionActive
? Runtime::Current()->GetClassLinker()->GetImagePointerSize()
: sizeof(void*);
//[1.3]
ArtMethod* result = klass->GetDeclaredConstructor(self, hs.NewHandle(args), pointer_size);
//[1.4]
return result != nullptr
? mirror::Constructor::CreateFromArtMethod<kTransactionActive>(self, result)
: nullptr;
}
1.3 mirror::Class::GetDeclaredConstructor
ArtMethod* Class::GetDeclaredConstructor(Thread* self,
Handle<mirror::ObjectArray<mirror::Class>> args, size_t pointer_size) {
//迭代每一个Direct Method, [1.3.1]
//m是ArtMethod
for (auto& m : GetDirectMethods(pointer_size)) {
// 跳过<clinit>方法, <clinit>是类的初始化方法,不是构造函数,所以跳过
if (m.IsStatic() || !m.IsConstructor()) {
continue;
}
// May cause thread suspension and exceptions.
// GetInterfaceMethodIfProxy方法一般情况下都是直接返回m的this引用
// EqualParameters方法用来判断传入的参数是否与方法本身的参数相同
if (m.GetInterfaceMethodIfProxy(sizeof(void*))->EqualParameters(args)) {
return &m;
}
if (UNLIKELY(self->IsExceptionPending())) {
return nullptr;
}
}
return nullptr;
}
1.3.1 mirror::Class::GetDirectMethods
inline IterationRange<StrideIterator<ArtMethod>> Class::GetDirectMethods(size_t pointer_size) {
CheckPointerSize(pointer_size);
return GetDirectMethodsSliceUnchecked(pointer_size).AsRange();
}
可以看到,GetDirectMethods
实质上就是封装调用了GetDirectMethodsSliceUnchecked
,GetDirectMethodsSliceUnchecked
定义在/art/runtime/mirror/class-inl.h
///art/runtime/mirror/class-inl.h
inline ArraySlice<ArtMethod> Class::GetDirectMethodsSliceUnchecked(size_t pointer_size) {
return ArraySlice<ArtMethod>(GetMethodsPtr(), //返回LengthPrefixedArray<ArtMethod>*,实质上封装的是当前类的Method数组指针
GetDirectMethodsStartOffset(),//返回Direct Method的起始偏移地址
GetVirtualMethodsStartOffset(),//返回Virtual Method的起始偏移地址
ArtMethod::Size(pointer_size),//pointer_size实质上是sizeof(void *)
ArtMethod::Alignment(pointer_size));
}
ArraySlice
定义在/art/runtime/base/array_slice.h
/art/runtime/base/array_slice.h
ArraySlice(LengthPrefixedArray<T>* array,
uint32_t start_offset,
uint32_t end_offset,
size_t element_size = sizeof(T),
size_t alignment = alignof(T))
: array_(nullptr),
size_(end_offset - start_offset),//Virtual Method的起始地址减去Direct Method的起始地址,这一段存储的全部是Direct Method
element_size_(element_size) {//每一个element的大小都是sizeof(void *)
...
if (size_ != 0) {
...
//T实质上是ArtMethod, 而array_的声明是T* array_,所以array_实质是ArtMethod*
//实际就是将array_指向ArtMethod数组
array_ = &array->At(start_offset, element_size_, alignment);
}
}
//AsRange的作用是获取所有Direct Method
IterationRange<StrideIterator<T>> AsRange() {
return size() != 0 ? MakeIterationRange(begin(), end())
: MakeEmptyIterationRange(StrideIterator<T>(nullptr, 0));
}
//指向ArtMethod数组的起始
StrideIterator<T> begin() {
return StrideIterator<T>(&AtUnchecked(0), element_size_);
}
//size_是DirectMethods的长度
StrideIterator<T> end() {
return StrideIterator<T>(&AtUnchecked(size_), element_size_);
}
T& AtUnchecked(size_t index) {
return *reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(array_) + index * element_size_);
}
StrideIterator
定义在/art/runtime/stride_iterator.h
, StrideIterator
继承自std::iterator
,并且重写了操作符++
:
template<typename T>
class StrideIterator : public std::iterator<std::forward_iterator_tag, T> {
...
StrideIterator(T* ptr, size_t stride): ptr_(reinterpret_cast<uintptr_t>(ptr)),
stride_(stride) {}
StrideIterator operator++() { // Value after modification.
ptr_ += stride_;
return *this;
}
...
}
从上面的代码中可以看出,mirror::Class::GetDirectMethods
方法简单来说执行了以下几步:
- 获取Direct Method的数组
- 根据获取到的数组,封装得到Direct Method数组的
iterator
,这样就可以通过for循环迭代Direct Method数组
1.4 mirror::Constructor::CreateFromArtMethod
mirror::Constructor
类定义在/art/runtime/mirror/method.h
//继承自AbstractMethod, AbstractMethod定义在/art/runtime/mirror/abstract_method.h
class MANAGED Constructor: public AbstractMethod {
public:
template <bool kTransactionActive = false>
static Constructor* CreateFromArtMethod(Thread* self, ArtMethod* method)
SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
static mirror::Class* StaticClass() SHARED_REQUIRES(Locks::mutator_lock_) {
return static_class_.Read();
}
static void SetClass(Class* klass) SHARED_REQUIRES(Locks::mutator_lock_);
static void ResetClass() SHARED_REQUIRES(Locks::mutator_lock_);
static mirror::Class* ArrayClass() SHARED_REQUIRES(Locks::mutator_lock_) {
return array_class_.Read();
}
static void SetArrayClass(Class* klass) SHARED_REQUIRES(Locks::mutator_lock_);
static void ResetArrayClass() SHARED_REQUIRES(Locks::mutator_lock_);
static void VisitRoots(RootVisitor* visitor) SHARED_REQUIRES(Locks::mutator_lock_);
private:
static GcRoot<Class> static_class_; // java.lang.reflect.Constructor.class.
static GcRoot<Class> array_class_; // [java.lang.reflect.Constructor.class.
};
CreateFromArtMethod
的实现在/art/runtime/mirror/method.cc
template <bool kTransactionActive> //kTransactionActive默认为false
Constructor* Constructor::CreateFromArtMethod(Thread* self, ArtMethod* method) {
...
//生成java.lang.reflect.Constructor对象并转换为Constructor*指针
auto* ret = down_cast<Constructor*>(StaticClass()->AllocObject(self));
if (LIKELY(ret != nullptr)) {
//将Constructor*指针向上转型为AbstractMethod*指针,并调用AbstractMethod的CreateFromArtMethod
static_cast<AbstractMethod*>(ret)->CreateFromArtMethod<kTransactionActive>(method);
}
return ret;
}
//设置构造函数的基本信息,如accessFlag,methodIndex等
template <bool kTransactionActive> //kTransactionActive默认为false
bool AbstractMethod::CreateFromArtMethod(ArtMethod* method) {
auto* interface_method = method->GetInterfaceMethodIfProxy(
kTransactionActive ? Runtime::Current()->GetClassLinker()->GetImagePointerSize()
: sizeof(void*));
SetArtMethod<kTransactionActive>(method);
SetFieldObject<kTransactionActive>(DeclaringClassOffset(), method->GetDeclaringClass());
SetFieldObject<kTransactionActive>(
DeclaringClassOfOverriddenMethodOffset(), interface_method->GetDeclaringClass());
SetField32<kTransactionActive>(AccessFlagsOffset(), method->GetAccessFlags());
SetField32<kTransactionActive>(DexMethodIndexOffset(), method->GetDexMethodIndex());
return true;
}
二. Constructor.newInstance
public T newInstance(Object... args) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//一般情况下,serializationClass为null
if (serializationClass == null) {
return newInstance0(args);
} else {
return (T) newInstanceFromSerialization(serializationCtor, serializationClass);
}
}
private native T newInstance0(Object... args) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException;
2.1 newInstance0
newInstance0
的实现在/art/runtime/native/java_lang_refrect_Constructor
static jobject Constructor_newInstance0(JNIEnv* env, jobject javaMethod, jobjectArray javaArgs) {
ScopedFastNativeObjectAccess soa(env);
mirror::Constructor* m = soa.Decode<mirror::Constructor*>(javaMethod);
StackHandleScope<1> hs(soa.Self());
Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass()));
//抽象类不允许创建对象
if (UNLIKELY(c->IsAbstract())) {
soa.Self()->ThrowNewExceptionF("Ljava/lang/InstantiationException;", "Can't instantiate %s %s",
c->IsInterface() ? "interface" : "abstract class",
PrettyDescriptor(c.Get()).c_str());
return nullptr;
}
// 如果构造函数不可访问且Class不是public
if (!m->IsAccessible() && !c->IsPublic()) {
//回退两个栈帧,newInstance0一般都是通过Constructor.newInstance(Object... arg0)调用
auto* caller = GetCallingClass(soa.Self(), 2);
if (caller != nullptr && !caller->CanAccess(c.Get())) {
if (PrettyDescriptor(c.Get()) == "dalvik.system.DexPathList$Element") {
LOG(WARNING) << "The dalvik.system.DexPathList$Element constructor"
is not accessible by default. This is a temporary "
"workaround for backwards compatibility with class-loader hacks."
"Please update your application.";
} else {
soa.Self()->ThrowNewExceptionF(
"Ljava/lang/IllegalAccessException;", "%s is not accessible from %s",
PrettyClass(c.Get()).c_str(), PrettyClass(caller).c_str());
return nullptr;
}
}
}
//确保类已经被解析完成
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(soa.Self(), c, true, true)) {
DCHECK(soa.Self()->IsExceptionPending());
return nullptr;
}
bool movable = true;
//如果当前要创建对象的类是java.lang.Class
if (!kMovingClasses && c->IsClassClass()) {
movable = false;
}
// String constructor is replaced by a StringFactory method in InvokeMethod.
if (c->IsStringClass()) {
return InvokeMethod(soa, javaMethod, nullptr, javaArgs, 2);
}
//如果类是java.lang.Class,则调用Class::AllocNonMovableObject创建对象
mirror::Object* receiver =
movable ? c->AllocObject(soa.Self()) : c->AllocNonMovableObject(soa.Self());
if (receiver == nullptr) {
return nullptr;
}
jobject javaReceiver = soa.AddLocalReference<jobject>(receiver);
InvokeMethod(soa, javaMethod, javaReceiver, javaArgs, 2);
// Constructors are ()V methods, so we shouldn't touch the result of InvokeMethod.
return javaReceiver;
}
从上述代码中可以得出:
- 如果类是抽象类,则不允许创建对象
- 如果要创建的类不是public且构造函数不可访问,则抛出
IllegalAccessException
(dalvik.system.DexPathList$Element
除外) - 创建对象之前,要确保类已经完成了解析
- 如果要创建对象的类是
java.lang.String
,则特别对待,最终要调用java.lang.StringFactory
来创建String对象
2.2 InvokeMethod
InvokeMethod
的实现在/art/runtime/reflection.cc
jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaMethod,
jobject javaReceiver, jobject javaArgs, size_t num_frames) {
//如果函数调用栈不对,则抛出StackOverFlowError
...
//将javaMethod即java层的Constructor对象转换为mirror::AbstractMethod*
//java层的Constructor类对应mirror::Constructor,而mirror::Constructor继承自mirror::AbstractMethod
auto* abstract_method = soa.Decode<mirror::AbstractMethod*>(javaMethod);
const bool accessible = abstract_method->IsAccessible();
ArtMethod* m = abstract_method->GetArtMethod();
mirror::Class* declaring_class = m->GetDeclaringClass();
//一般情况下,要创建对象的类已经被解析过
if (UNLIKELY(!declaring_class->IsInitialized())) {
...
}
mirror::Object* receiver = nullptr;
if (!m->IsStatic()) {
//如果要创建对象的类是String,则用StringFactory来创建String对象
if (declaring_class->IsStringClass() && m->IsConstructor()) {
jmethodID mid = soa.EncodeMethod(m);
//根据methodId获取对应的StringFactory的方法
m = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
} else {
receiver = soa.Decode<mirror::Object*>(javaReceiver);
if (!VerifyObjectIsClass(receiver, declaring_class)) {
return nullptr;
}
// 查找虚拟方法的真正实现
m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m, sizeof(void*));
}
}
// 将java层的参数转换为mirror::ObjectArray数组
auto* objects = soa.Decode<mirror::ObjectArray<mirror::Object>*>(javaArgs);
auto* np_method = m->GetInterfaceMethodIfProxy(sizeof(void*));
//获取要调用的方法在dex文件中记录的参数列表
const DexFile::TypeList* classes = np_method->GetParameterTypeList();
uint32_t classes_size = (classes == nullptr) ? 0 : classes->Size();
uint32_t arg_count = (objects != nullptr) ? objects->GetLength() : 0;
//判断传入的参数与dex文件中记录的参数是否一致,不一致抛出IllegalArgumentException
if (arg_count != classes_size) {
...//throw IllegalArgumentException
return nullptr;
}
// 验证类的accessible
mirror::Class* calling_class = nullptr;
if (!accessible && !VerifyAccess(soa.Self(), receiver, declaring_class, m->GetAccessFlags(),
&calling_class, num_frames)) {
...//throw IllegalAccessException
return nullptr;
}
JValue result;
uint32_t shorty_len = 0;
//获取method的方法声明字符串
const char* shorty = np_method->GetShorty(&shorty_len);
ArgArray arg_array(shorty, shorty_len);
//创建参数数组
if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, np_method)) {
CHECK(soa.Self()->IsExceptionPending());
return nullptr;
}
//核心调用,执行方法, [2.3]
InvokeWithArgArray(soa, m, &arg_array, &result, shorty);
// 如果有异常发生,则抛出InvocationTargetException
if (soa.Self()->IsExceptionPending()) {
... //创建InvocationTargetException对象实例,并抛出
return nullptr;
}
// 如果是基础类型,则自动装箱并返回
return soa.AddLocalReference<jobject>(BoxPrimitive(Primitive::GetType(shorty[0]), result));
}
2.3 InvokeWithArgArray
static void InvokeWithArgArray(const ScopedObjectAccessAlreadyRunnable& soa,
ArtMethod* method, ArgArray* arg_array, JValue* result,
const char* shorty)
SHARED_REQUIRES(Locks::mutator_lock_) {
uint32_t* args = arg_array->GetArray();
...
//最后实际调用ArtMethod::Invoke
method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, shorty);
}
2.4 总结
可以看到最后Constructor.newInstance
最后实际调用的是ArtMethod::Invoke
方法,在执行ArtMethod::Invoke
之前的所有工作主要是确保类已经被解析,以及生成参数,另外如果要创建对象的类是String
类,则都转而调用相应的StringFactory
的方法,由此可以看出创建String对象都是由StringFactory完成.
ArtMethod::Invoke
方法涉及到了方法具体的执行逻辑(执行本地机器指令还是解释执行,以及调用到其他方法是entryPoint等),另外Android 7.0还加入了JIT机制,这些需要花时间慢慢掌握.
下面这张图是官网的JIT的工作流程图