JVM到底怎么进行类加载器的呢?

来源:互联网 发布:嵌入式linux开机进度 编辑:程序博客网 时间:2024/06/07 14:58



题目:Java的类加载器有哪些;每个类加载器都加载哪些类;这些类加载之间的父子关系是怎样的;什么是双亲委派模型;Java的类加载器为什么要使用双亲委派模型;如何自定义自己的类加载器,自己的类加载器和Java自带的类加载器关系如何处理?

考点

这个题目主要考查ClassLoader的工作机制,即它是怎么把Class加载到JVM中?考查这个题目便于我们在日常的工作中更好的理解Java程序的工作原理。

类加载器有那些?

BootstrapClassLoaderExtClassLoaderAppClassLoaderURLClassLoaderWebappClassLoader

每个类加载器加载了那些类?

  • BootstrapClassLoader(启动类加载器):主要加载JVM自身工作需要的类,完全由JVM自己控制;它是所有类加载器的父加载器,位于jre/lib/rt.jar。
  • ExtClassLoader(扩展类加载器):它既装载除了基本的Java API以外的扩展类,也负责装载其他的安全扩展功能;位于System.getProperty("java.ext.dirs")指向的目录。
  • AppClassLoader(系统类加载器):负责加载用户在$CLASSPATH里指定的类,位于System.getProperty("java.class.path")。
  • User-defined ClassLoader(用户自定义类加载器):直接用代码实现的类加载器,如:WebappClassLoader。

类是怎么加载的,为什么要使用双亲委派模型?

它们使用双亲委派的模型来加载;基于三个机制:委托、可见性和单一性

  1. 委托:当一个类加载和初始化的时候,类仅在有需要加载的时候被加载。首先加载这个类的请求由AppClassLoader委托给它的父类加载器ExtClassLoader,然后再委托给BootstrapClassLoader。BootstrapClassLoader会先看看rt.jar中有没有这个类,如果并没有这个类,就把这个请求返回到ExtClassLoader,它会查看jre/lib/ext目录下有没有这个类,如果这个类被ExtClassLoader找到了,那么它将被加载,而AppClassLoader不会加载这个类;而如果这个类没有被ExtClassLoader找到,那么再由AppClassLoader从classpath中寻找。
  2. 可见性:子类加载器可以看到父类加载器加载的类,而反之则不行。
  3. 单一性:父加载器加载过的类不能被子加载器加载第二次。

JVM怎么加载Class文件到内存?

  • 隐式加载:不通过调用ClassLoader来加载需要的类,而是通过JVM自动加载所需的类到内存。如,继承与类引用。
  • 显示加载:通过ClassLoader类来加载类的方式。如,this.getClass().getClassLoader().loadClass()/Class.forName()/自定义的类加载器的findClass()。

如何自定义类加载器,及怎么处理加载器关系?

自己定义的类加载器一般继承ClassLoader/URLClassLoader。

一般只需要重写findClass()方法;同一个类如果被两个类加载器加载,那么JVM不认为使相同的类;检查被请求的类是否已经被加载到命名空间,如果已被加载,则直接返回。

用到的代码:

private void hi(HttpServletRequest request, HttpServletResponse response) throws IOException {       ClassLoader classLoader = HelloServlet.class.getClassLoader();       while (classLoader != null) {           response.getWriter().write(classLoader.getClass().getCanonicalName()+"\n");           classLoader = classLoader.getParent();       }}

执行结果:

org.apache.catalina.loader.WebappClassLoaderjava.net.URLClassLoadersun.misc.Launcher.AppClassLoadersun.misc.Launcher.ExtClassLoader

分析一下常见类加载错误有那些,是怎么产生的?

ClassNotFoundExceptionNoClassDefFoundErrorUnsatisfiedLinkErrorClassCastExceptionExceptionInInitializerError

记住,这里全部都是干货!!!