Java 运行时环境(JRE)是如何加载类的呢? 这玩意水太深,就谈谈一个类是怎么加载的,jvm是怎么工作的。
JVM启动后有三个基本层次的类加载器,先上图:
其中bootstap classloader 是c++写的,jvm启动后,它加载java环境运行所需要的一些class文件(java.* javax.*等包),例如rt.jar,但还有其他的,大家要想看的话可以测试下看加载了哪些:
URL [] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs(); for (URL url:urls) { System.out.println(url.toExternalForm() ); }
extension classloader ,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中JAR的类包。
Application classloader(也有叫system classloader),就负责加载classpath里面设置的类。
概念性的东西不多讲,java的类加载都在java.lang.ClassLoader里面.采用委托机制。
来看看在运行时需要一个类时是怎么工作的吧。
1、jre需要一个类,假如为a.class,会让Application classloader找,
2、Application classloade 就委托他的上一层次加载器extension classloader找,
3、Extension classloader 委托他的上一层,让bootstap classloader 找,
4、Bootstrap classloader是最高层的,他就亲自找啊,但是没有找到,于是就告诉Extension classloader说他这没有,你自己找去。
5、Extesion classloader 就在ext目录下找,发现也没,于是说:“兄弟,哥这也没,你自己找去。”
6、于是application classloader就在classpath里面找,如果找到了返回给jre,如果没有找到,就告诉jre没找到,jre此时非常生气:“李大爷的,逗了这么大圈,居然没有找到,靠:ClassNotFoundException ”