java类加载器ClassLoader

类加载器获取资源路径
一、同一工程中:

          String path = Thread.currentThread().getContextClassLoader().getResource(".").getPath(); 
           System.out.println(path); 
     
           String string = Sample1.class.getClassLoader().getResource(".").getPath(); 
           System.out.println(string); 
     
           String string2 = Sample1.class.getResource(".").getPath(); 
           System.out.println(string2); 

测试结果:

    /D:/workspaces/workspace7/demo1/target/classes/ 
    /D:/workspaces/workspace7/demo1/target/classes/ 
    /D:/workspaces/workspace7/demo1/target/classes/com/alibaba/ 

说明:

Classloader读取文件(即方式1和方法2)都是从classpath开始查找文件;方式3从当前类所在的目录下开始查找文件

二、不同的工程中,实验如下:

    public class Sample2 { 
        public static void main(String[] args) { 
            Sample1 sample1 = new Sample1(); 
            sample1.print(); 
        } 
    } 

执行结果:

    /D:/workspaces/workspace7/demo2/target/classes/ 
    /D:/workspaces/workspace7/demo2/target/classes/ 
这种方式,是从当前类的位置触发
    /D:/workspaces/workspace7/demo1/target/classes/com/alibaba/ 

说明:Classloader获取的内容始终从调用方出发;而一般类的资源获取是从类自身的位置触发

Java类加载器ClassLoader总结

整个加载类的过程如下图:


java类加载器ClassLoader_第1张图片
图片.png

JAVA类装载方式,有两种:
1.隐式装载, 程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中。 2.显式装载, 通过class.forname()等方法,显式加载需要的类

类加载的动态性体现:
一个应用程序总是由n多个类组成,Java程序启动时,并不是一次把所有的类全部加载后再运行,它总是先把保证程序运行的基础类一次性加载到jvm中,其它类等到jvm用到的时候再加载,这样的好处是节省了内存的开销,因为java最早就是为嵌入式系统而设计的,内存宝贵,这是一种可以理解的机制,而用到时再加载这也是java动态性的一种体现

java类装载器

JDK 默认提供了如下几种ClassLoader

Bootstrp loader  (引导类加载器)
  1. Bootstrp加载器是用C++语言写的,它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类。
ExtClassLoader   (extension扩展类加载器)
  1. Bootstrp loader加载ExtClassLoader,并且将ExtClassLoader的父加载器设置为Bootstrp loader.ExtClassLoader是用Java写的,具体来说就是 sun.misc.Launcher$ExtClassLoader,ExtClassLoader主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中类库。
AppClassLoader     (应用程序类加载器)
  1. Bootstrp loader加载完ExtClassLoader后,就会加载AppClassLoader,并且将AppClassLoader的父加载器指定为 ExtClassLoader。AppClassLoader也是用Java写成的,它的实现类是 sun.misc.Launcher$AppClassLoader,另外我们知道ClassLoader中有个getSystemClassLoader方法,此方法返回的正是AppclassLoader.AppClassLoader主要负责加载classpath所指定的位置的类或者是jar文档,它也是Java程序默认的类加载器。

综上所述,它们之间的关系可以通过下图形象的描述


java类加载器ClassLoader_第2张图片
图片.png

类加载器之间是如何协调工作的

前面说了,java中有三个类加载器,问题就来了,碰到一个类需要加载时,它们之间是如何协调工作的,即java是如何区分一个类该由哪个类加载器来完成呢。 在这里java采用了委托模型机制,这个机制简单来讲,就是“类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果Parent 找不到,那么才由自己依照自己的搜索路径搜索类”

你可能感兴趣的:(java类加载器ClassLoader)