ClassLoader的具体作用就是将class字节码文件加载到jvm虚拟机中去
但是jvm在启动的时候并不会一次性加载完成 而是需要根据需要去动态加载
第一步 编写Java代码
第二步 通过首先通过编译器 javac xx.java 编译成.class文件
第三步 ClassLoader加载字节码文件到jvm虚拟机 Class.forName("xxx.com.A")
java环境变量
JAVA_HOME
PATH
CLASSPATH
Java的类加载器 主要有3个:
Bootstrap ClassLoader
Extention ClassLoader
AppClass Loader
android里面的类加载器
UrlClassLoader
DexClassLoader
原理分析:
第一步 用户编写Java代码
第二步 编译 (javac xx.java)
第三步 当我们创建new 对象的时候 或者Class.forName('包名+类名') 它的原理
其实是这么做的 首先 创建了一个ClassLoader 对象 (类加载器)
这个时候翻开ClassLoader.java源码 默认构造器 不过这个构造方法是私有的 我们是通过静态方法来获取AppClassLoader实例的, 发现有一个getSystemLoader的方法是获取ClassLoader
然后我们翻开这个源码 我们发现有一个initSystemLoader的方法 代码如下:
private static synchronized void initSystemClassLoader() {
if (!sclSet) { //如果sclSet==false
if (scl != null)
throw new IllegalStateException("recursive invocation");
sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); //首先获取Laucher 这个就是获取外部类Launcher实例,通过这个实例来获取AppClassLoader内部类的实例
if (l != null) {
Throwable oops = null;
scl = l.getClassLoader();// 原来是在这里获取ClassLoader实例的
try {
scl = AccessController.doPrivileged(
new SystemClassLoaderAction(scl));
} catch (PrivilegedActionException pae) {
oops = pae.getCause();
if (oops instanceof InvocationTargetException) {
oops = oops.getCause();
}
}
if (oops != null) {
if (oops instanceof Error) {
throw (Error) oops;
} else {
// wrap the exception
throw new Error(oops);
}
}
}
sclSet = true;
}
}
//然后重点进入Launcher.java这个文件 看看它的默认构造器 (主要是做了委托这件事)
public Launcher() {
Launcher.ExtClassLoader var1;
try {
var1 = Launcher.ExtClassLoader.getExtClassLoader();
} catch (IOException var10) {
throw new InternalError("Could not create extension class loader", var10);
}
try {
this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
} catch (IOException var9) {
throw new InternalError("Could not create application class loader", var9);
}
Thread.currentThread().setContextClassLoader(this.loader);
String var2 = System.getProperty("java.security.manager");
if (var2 != null) {
SecurityManager var3 = null;
if (!"".equals(var2) && !"default".equals(var2)) {
try {
var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();
} catch (IllegalAccessException var5) {
} catch (InstantiationException var6) {
} catch (ClassNotFoundException var7) {
} catch (ClassCastException var8) {
}
} else {
var3 = new SecurityManager();
}
if (var3 == null) {
throw new InternalError("Could not create SecurityManager: " + var2);
}
System.setSecurityManager(var3);
}
网友评论