sun.misc.Launcher类,类中定义了几个类加载器。
AppClassLoader 系统类加载器
ExtClassLoader 扩展类加载器
关于类加载器的一些东西,可以看这篇类加载
Launcher的getClassPath(String classPath):
private static File[] getClassPath(String classPath) {
File[] classFiles;
if(classPath != null) {
int fileCount = 1;
int var5; //移动游标
int separatorIndex; // ;符号的位置
for(var5 = 0; (separatorIndex = classPath.indexOf(File.pathSeparator, var5)) != -1; var5 = separatorIndex + 1) {
++fileCount;
}
classFiles = new File[fileCount];
int var2 = 0;
for(var5 = 0; (separatorIndex = classPath.indexOf(File.pathSeparator, var5)) != -1; var5 = separatorIndex + 1) {
if(separatorIndex - var5 > 0) {
classFiles[var2++] = new File(classPath.substring(var5, separatorIndex));
} else {
classFiles[var2++] = new File(".");
}
}
if(var5 < classPath.length()) {//classPath,不是以分号结尾时,把分号后面的作为一个文件路径放入数组
classFiles[var2++] = new File(classPath.substring(var5));
} else {
classFiles[var2++] = new File(".");
}
if(var2 != fileCount) {//以var2为准,如果 原始数组没填满,则复制到新数组中。
File[] var6 = new File[var2];
System.arraycopy(classFiles, 0, var6, 0, var2);
classFiles = var6;
}
} else {
classFiles = new File[0];
}
return classFiles;
}
AppClassLoader类:
/**
* var1 类全名
* var2 是否连接该类
*/
public Class<?> loadClass(String var1, boolean var2) throws ClassNotFoundException {
int var3 = var1.lastIndexOf(46);
if(var3 != -1) {
SecurityManager var4 = System.getSecurityManager();
if(var4 != null) {
var4.checkPackageAccess(var1.substring(0, var3));
}
}
if(this.ucp.knownToNotExist(var1)) {//一般都是false,想要返回TRUE可能需要设置启动参数lookupCacheEnabled 为true。为true时,具体的逻辑也是C++写的,所以做了什么就不大清楚了。
Class var5 = this.findLoadedClass(var1); //如果这个类已经被这个类加载器加载,则返回这个类,否则返回Null
if(var5 != null) {
if(var2) {
this.resolveClass(var5); //如果该类没有被link(连接),则连接,否则什么都不做
}
return var5;
} else {
throw new ClassNotFoundException(var1);
}
} else {
return super.loadClass(var1, var2);
}
}
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;
}
}
protected Class<?> findClass(final String name)
throws ClassNotFoundException
{
final Class<?> result;
try {
result = AccessController.doPrivileged(
new PrivilegedExceptionAction<Class<?>>() {
public Class<?> run() throws ClassNotFoundException {
String path = name.replace('.', '/').concat(".class");
Resource res = ucp.getResource(path, false);
if (res != null) {
try {
return defineClass(name, res);
} catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
} else {
return null;
}
}
}, acc);
} catch (java.security.PrivilegedActionException pae) {
throw (ClassNotFoundException) pae.getException();
}
if (result == null) {
throw new ClassNotFoundException(name);
}
return result;
}
扩展类加载器,并没有覆盖Loadclass方法,只是定义了一些加载路径,再考虑到一般它由jvm控制调用,所以也就不深究了。