0%

loadClass、findClass、defineClass

文章字数:265,阅读全文大约需要1分钟

loadClass

加载一个类,传入名字或位置

  1. 调用findLoadedClass(String)检测是否这个类已经被加载
  2. 没有被加载则调用父类的loadClass()方法,直到找到或者父类为空(说明是启动类加载器)
  3. 到了启动类加载器都没有就调用findClass(String)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
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.
long t1 = System.nanoTime();
c = findClass(name);

// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}

findClass

  1. 根据名称或位置加载.class字节码,然后使用defineClass
  2. 通常由子类去实现
    loadClass的源码可以看到,最后如果还是找不到类就会调用findClass。但是ClassLoaderfindClass是直接抛出异常,自定义类加载器需要实现此方法。
    1
    2
    3
    protected Class<?> findClass(String name) throws ClassNotFoundException {
    throw new ClassNotFoundException(name);
    }

definclass

  1. 把字节码转化为Class