ClassLoader的一次探索

来自深入java虚拟机的介绍,关于JVM加载class的原理,主要有几个重点。

1. ClassLoder的种类
内置的ClassLoader有3种,一是BootstrapClassLoader,这是根loader,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等;二是ExtensionClassLoader,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目下的所有jar;三是AppClassLoader:负责加载应用程序classpath目录下的所有jar和class文件。

2.双亲委派
逻辑是,每当要加载一个类时,都会先让父加载器先加载来避免一些安全问题
关键源码:
try {
		if (parent != null) {
		    c = parent.loadClass(name, false);
		} else {
		    c = findBootstrapClass0(name);
		}

	    } catch (ClassNotFoundException e) {
	        // If still not found, then invoke findClass in order
	        // to find the class.
	        c = findClass(name);
	    }


3.一个有意思的例子
在同一个项目中,同时引用两个定义了Class Test的jar包,调用的时候发现,只有其中一个jar包会在编译中起作用,原因就是加载器在加载的时候会总是发现Test类已经被加载了,而忽略另外的Test类,删掉起作用的jar包之后,另一个Test类才能起作用,从另外一个角度上说,包名相同类名也相同的情况,应该在实践中绝对避免。

4.动态加载的class类
观察Class.forName()方法的源码,发现它的实现是调用了一个本地方法,查找资料得知,这里的本地方法,应该是通过加载器的loadClassInternal方法来找对应的类,而这一步,就回到了上述的双亲委派的过程了。

5.自定义的加载器
要自定义加载器,主要是要实现findClass方法,不管用什么方式,从网络也好,从文件也好,找到Class文件,序列化成字节流后通过defineClass方法来把字节流变成一个Class对象,返回到加载器,这个类的加载的流程就完成了。

你可能感兴趣的:(原理,自定义,classloder)