安卓10
java层
libcore\ojluni\src\main\java\java\lang\ClassLoader.java
protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException
{// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.c = findClass(name);}}return c;
}/*** Returns the class with the given <a href="#name">binary name</a> if this* loader has been recorded by the Java virtual machine as an initiating* loader of a class with that <a href="#name">binary name</a>. Otherwise* <tt>null</tt> is returned.** @param name* The <a href="#name">binary name</a> of the class** @return The <tt>Class</tt> object, or <tt>null</tt> if the class has* not been loaded** @since 1.1*/protected final Class<?> findLoadedClass(String name) {ClassLoader loader;if (this == BootClassLoader.getInstance())loader = null;elseloader = this;return VMClassLoader.findLoadedClass(loader, name);}
libcore\libart\src\main\java\java\lang\VMClassLoader.java
@FastNativenative static Class findLoadedClass(ClassLoader cl, String name);
native层
art\runtime\native\java_lang_VMClassLoader.cc
static jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoader,jstring javaName) {// Hard-coded performance optimization: We know that all failed libcore calls to findLoadedClass// are followed by a call to the the classloader to actually// load the class.if (loader != nullptr) {// Try the common case.StackHandleScope<1> hs(soa.Self());c = VMClassLoader::FindClassInPathClassLoader(cl,soa,soa.Self(),descriptor.c_str(),descriptor_hash,hs.NewHandle(loader));if (c != nullptr) {return soa.AddLocalReference<jclass>(c);}}// The class wasn't loaded, yet, and our fast-path did not apply (e.g., we didn't understand the// classloader chain).return nullptr;
}static ObjPtr<mirror::Class> FindClassInPathClassLoader(ClassLinker* cl,ScopedObjectAccessAlreadyRunnable& soa,Thread* self,const char* descriptor,size_t hash,Handle<mirror::ClassLoader> class_loader)REQUIRES_SHARED(Locks::mutator_lock_) {ObjPtr<mirror::Class> result;if (cl->FindClassInBaseDexClassLoader(soa, self, descriptor, hash, class_loader, &result)) {DCHECK(!self->IsExceptionPending());return result;}if (self->IsExceptionPending()) {self->ClearException();}return nullptr;}
art\runtime\class_linker.cc
bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnable& soa,Thread* self,const char* descriptor,size_t hash,Handle<mirror::ClassLoader> class_loader,/*out*/ ObjPtr<mirror::Class>* result) {// Termination case: boot class loader.if (IsBootClassLoader(soa, class_loader.Get())) {*result = FindClassInBootClassLoaderClassPath(self, descriptor, hash);return true;}if (IsPathOrDexClassLoader(soa, class_loader) || IsInMemoryDexClassLoader(soa, class_loader)) {// For regular path or dex class loader the search order is:// - parent// - shared libraries// - class loader dex files// Handles as RegisterDexFile may allocate dex caches (and cause thread suspension).StackHandleScope<1> hs(self);Handle<mirror::ClassLoader> h_parent(hs.NewHandle(class_loader->GetParent()));if (!FindClassInBaseDexClassLoader(soa, self, descriptor, hash, h_parent, result)) {return false; // One of the parents is not supported.}if (*result != nullptr) {return true; // Found the class up the chain.}if (!FindClassInSharedLibraries(soa, self, descriptor, hash, class_loader, result)) {return false; // One of the shared library loader is not supported.}if (*result != nullptr) {return true; // Found the class in a shared library.}// Search the current class loader classpath.*result = FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader);return !soa.Self()->IsExceptionPending();}if (IsDelegateLastClassLoader(soa, class_loader)) {// For delegate last, the search order is:// - boot class path// - shared libraries// - class loader dex files// - parent*result = FindClassInBootClassLoaderClassPath(self, descriptor, hash);if (*result != nullptr) {return true; // The class is part of the boot class path.}if (self->IsExceptionPending()) {// Pending exception means there was an error other than ClassNotFound that must be returned// to the caller.return false;}if (!FindClassInSharedLibraries(soa, self, descriptor, hash, class_loader, result)) {return false; // One of the shared library loader is not supported.}if (*result != nullptr) {return true; // Found the class in a shared library.}*result = FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader);if (*result != nullptr) {return true; // Found the class in the current class loader}if (self->IsExceptionPending()) {// Pending exception means there was an error other than ClassNotFound that must be returned// to the caller.return false;}// Handles as RegisterDexFile may allocate dex caches (and cause thread suspension).StackHandleScope<1> hs(self);Handle<mirror::ClassLoader> h_parent(hs.NewHandle(class_loader->GetParent()));return FindClassInBaseDexClassLoader(soa, self, descriptor, hash, h_parent, result);}// Unsupported class loader.*result = nullptr;return false;
}