loadclass java_ClassLoader loadClass java层源码查看

不管是 fdex2 脱壳的核心思想,还是 Android 的热修复技术等,当中都有 loadClass 的身影。

java类装载:

5d9378d881ca61e1e1716f73291fff4c.png

ClassLoader loadClass:默认情况下,只加载目标类,并不进行链接和初始化

Class.forName: 默认情况下,加载目标类,如果类之前没有被初始化,则会进行类的初始化,主要体现在静态区域的初始化

libcore/ojluni/src/main/java/java/lang/ClassLoader.java

双亲委派机制加载类,如果双亲未加载且无法加载目标类,则调用 findClass 去加载,此方法由子类实现public Class> loadClass(String name) throws ClassNotFoundException {

return loadClass(name, false);

}

protected Class> loadClass(String name, boolean resolve)

throws ClassNotFoundException

{

// First, check if the class has already been loaded

Class> 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;

}

protected Class> findClass(String name) throws ClassNotFoundException {

throw new ClassNotFoundException(name);

}

libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.javapublic class BaseDexClassLoader extends ClassLoader {

/**

* Hook for customizing how dex files loads are reported.

*

* This enables the framework to monitor the use of dex files. The

* goal is to simplify the mechanism for optimizing foreign dex files and

* enable further optimizations of secondary dex files.

*

* The reporting happens only when new instances of BaseDexClassLoader

* are constructed and will be active only after this field is set with

* {@link BaseDexClassLoader#setReporter}.

*/

/* @NonNull */ private static volatile Reporter reporter = null;

private final DexPathList pathList;

@Override

protected Class> findClass(String name) throws ClassNotFoundException {

List suppressedExceptions = new ArrayList();

Class c = pathList.findClass(name, suppressedExceptions);

if (c == null) {

ClassNotFoundException cnfe = new ClassNotFoundException(

"Didn't find class \"" + name + "\" on path: " + pathList);

for (Throwable t : suppressedExceptions) {

cnfe.addSuppressed(t);

}

throw cnfe;

}

return c;

}

}

libcore/dalvik/src/main/java/dalvik/system/DexPathList.javapublic Class> findClass(String name, List suppressed) {

for (Element element : dexElements) {

Class> clazz = element.findClass(name, definingContext, suppressed);

if (clazz != null) {

return clazz;

}

}

if (dexElementsSuppressedExceptions != null) {

suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));

}

return null;

}

private Element[] dexElements;

this.dexElements = makeInMemoryDexElements(dexFiles, suppressedExceptions);

private static Element[] makeInMemoryDexElements(ByteBuffer[] dexFiles,

List suppressedExceptions) {

Element[] elements = new Element[dexFiles.length];

int elementPos = 0;

for (ByteBuffer buf : dexFiles) {

try {

DexFile dex = new DexFile(buf);

elements[elementPos++] = new Element(dex);

} catch (IOException suppressed) {

System.logE("Unable to load dex file: " + buf, suppressed);

suppressedExceptions.add(suppressed);

}

}

if (elementPos != elements.length) {

elements = Arrays.copyOf(elements, elementPos);

}

return elements;

}

/*package*/ static class Element {

/**

* A file denoting a zip file (in case of a resource jar or a dex jar), or a directory

* (only when dexFile is null).

*/

private final File path;

private final DexFile dexFile;

private ClassPathURLStreamHandler urlHandler;

private boolean initialized;

/**

* Element encapsulates a dex file. This may be a plain dex file (in which case dexZipPath

* should be null), or a jar (in which case dexZipPath should denote the zip file).

*/

public Element(DexFile dexFile, File dexZipPath) {

this.dexFile = dexFile;

this.path = dexZipPath;

}

public Class> findClass(String name, ClassLoader definingContext,

List suppressed) {

return dexFile != null ? dexFile.loadClassBinaryName(name, definingContext, suppressed)

: null;

}

}

libcore/dalvik/src/main/java/dalvik/system/DexFile.javapublic Class loadClassBinaryName(String name, ClassLoader loader, List suppressed) {

return defineClass(name, loader, mCookie, this, suppressed);

}

private static Class defineClass(String name, ClassLoader loader, Object cookie,

DexFile dexFile, List suppressed) {

Class result = null;

try {

result = defineClassNative(name, loader, cookie, dexFile);

} catch (NoClassDefFoundError e) {

if (suppressed != null) {

suppressed.add(e);

}

} catch (ClassNotFoundException e) {

if (suppressed != null) {

suppressed.add(e);

}

}

return result;

}

private static native Class defineClassNative(String name, ClassLoader loader, Object cookie,

DexFile dexFile)

throws ClassNotFoundException, NoClassDefFoundError;

总结:

loadClass(ClassLoader.java) -> findClass(BaseDexClassLoader.java) -> findClass(DexPathList.java) ->

findClass(DexPathList.java -> Element -> findClass) -> loadClassBinaryName(DexFile.java) ->

defineClass(DexFile.java) -> defineClassNative(DexFile.java) -> Native层

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值