classloader

一: classloader简介

1.classloader定义

java程序编译生成的.class文件加载到jvm中就是classloader要做的事儿。

2. .class文件是什么时候被加载到jvm中?

①执行new操作
Class.forName(“包路径+类名”)
Class.forName("包路径+类名",classloader)
classloader.loadclass("包路径+类名")
在已上几种情况下就会触发类加载器去相应路径下查找*.class,并创建Class对象

二: 实例

Java自带的Classloader

1.BootstrapClassloader:

引导类加载器,又称启动类加载器,是最顶层的类加器,主要用来加载Java核心类,如:rt.jarresource.jarcharsets.jar等,SunJVM中,执行java命令中-Xbootclasspath选项或使用-D选项指定sun.boot.class.path系统属性可以指定附加类,它不是java.lang.ClassLoader的子类,而是由JVM自身实现的该类c语言实现,Java程序访问不到该加载器。通过下面的代码可以查看该加载器加载了哪些jar包:

public static void main(String[] args) {
      URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
      for (int i = 0; i < urls.length; i++) {
          System.out.println("urls--->"+urls[i].toExternalForm());
      }
}
------------------------------本机的运行结果【这些是bootstarp来加载的】:---------------------------------------
urls--->file:/G:/java/jdk1.8.0_25/jre/lib/resources.jar
urls--->file:/G:/java/jdk1.8.0_25/jre/lib/rt.jar
urls--->file:/G:/java/jdk1.8.0_25/jre/lib/sunrsasign.jar
urls--->file:/G:/java/jdk1.8.0_25/jre/lib/jsse.jar
urls--->file:/G:/java/jdk1.8.0_25/jre/lib/jce.jar
urls--->file:/G:/java/jdk1.8.0_25/jre/lib/charsets.jar
urls--->file:/G:/java/jdk1.8.0_25/jre/lib/jfr.jar
urls--->file:/G:/java/jdk1.8.0_25/jre/classes
2.ExtClassloader:

扩展类加载器,主要负责加载java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的所有jar包或者由java.ext.dirs系统属性指定的jar包。放入这个目录下的jar包所对所有AppClassloader都是可见的(因为ExtClassloaderAppClassloader的父加载器),那么ext都是在哪些地方加载类的呢?请看:

System.out.println("ext---->"+System.getProperty("java.ext.dirs"));
--------------------------本机的运行结果:-------------------------------
ext---->G:\java\jdk1.8.0_25\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
3. AppClassloader

系统类加载器,又称应用类加载器,本文说的SystemClassloaderAppClassloader是一个东西,他负责在JVM启动时,加载来自在java命令中的-classpath或者java.class.path系统属性或者CLASSPATH操作系统属性指定的JAR包和类路径。调用ClassLoader.getSystemClassLoader()可以获取该类加载器。如果没有特别指定,则用户自定义的任何类加载器都将该类加载器作为它的父加载器,这点儿可以通过ClassLoader的无参构造函数可以知道,如下:

/**
     * Creates a new class loader using the <tt>ClassLoader</tt> returned by
     * the method {@link #getSystemClassLoader()
     * <tt>getSystemClassLoader()</tt>} as the parent class loader.
     *
     * <p> If there is a security manager, its {@link
     * SecurityManager#checkCreateClassLoader()
     * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
     * a security exception.  </p>
     *
     * @throws  SecurityException
     *          If a security manager exists and its
     *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
     *          of a new class loader.
     */
    protected ClassLoader() {
        this(checkCreateClassLoader(), getSystemClassLoader());
    }
-------------------执行以下代码即可获得classpath加载路径-------------------------------------

	System.out.println("classpath---->"+System.getProperty("java.class.path"));
4.各个类加载器的联系

在这里插入图片描述
用户自定义的无参类加载器的父类加载器默认为AppClassloader加载器,而AppClassloader加载器是ExtClassloader,通过下面的代码可以验证:

System.out.println("ParentClassLoader---->"+ ClassLoader.getSystemClassLoader().getParent());
-----------------------------本机运行结果:-------------------------
systemClassLoader---->sun.misc.Launcher$AppClassLoader@58644d46

一般我们都认为ExtClassloader的父类加载器是BootStrapClassloader,但是其实他们之间根本是没有父子关系的,只是在ExtClassloader找不到要加载的类的时候才会去委托Bootstrap加载器去加载,通过下面代码的验证:

System.out.println("ParentParentClassLoader---->"+ ClassLoader.getSystemClassLoader().getParent().getParent());
-----------------------------本机运行结果:-------------------------
ParentParentClassLoader---->null

三:类加载器的原理

Java类加载器使用的是双亲委派机制,也就是说子类类加载器在加载一个类的时候让父类去加载!使用这种方式的原因是:避免重复加载,当父类类加载器加载了该类的时候,就没有必要子类Classloader再加载一次了,主要是出于安全的考虑。如若没有这种机制,那我们就可以使用自定义的String来动态替代java核心api中定义的类型,这样存在很大的安全隐患,而双亲委派机制却可以很好的避免这种情况,因为String已经在启动的时候就被引导类加载器(BootStrapClassLoader)加载了,所以用户自定义的ClassLoader永远也不无加载自定义的String,除非你改变JDK中ClassLoader搜索类的默认算法。下面我们从源码看如何实现的这种机制:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值