Uninote
Uninote

JAVA类加载方式

隐式加载

通过new等途径生成的对象时,隐式调用类加载器加载对应的类到jvm中

显式加载

通过class.forname()等方法,显式加载需要的类

类加载的动态性体现

Java程序启动时,并不是一次把所有的类全部加载后再运行,先把保证程序运行的基础类一次性加载到jvm中,其它类等到jvm用到的时候再加载,是节省内存开销,而用到时再加载就是java动态性的一种体现

JDK 默认加载器

Bootstrap ClassLoader(启动类加载器)

C++语言实现,它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类

Extension ClassLoader (扩展类加载器)

Bootstrap ClassLoader加载Extension ClassLoader,并且将Extension ClassLoader的父加载器设置为Bootstrap ClassLoader,实现类是sun.misc.Launcher$ExtClassLoader,Extension ClassLoader主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中的类库

Application ClassLoader(应用程序类加载器)

加载完Extension ClassLoader后,就会加载Application ClassLoader,并且将Application ClassLoader的父加载器指定为 Extension ClassLoader。实现类是 sun.misc.Launcher$AppClassLoader,ClassLoader中有个getSystemClassLoader方法,此方法返回的正是AppclassLoader.AppClassLoader主要负责加载classpath所指定的位置的类或者是jar文档,它也是Java程序默认的类加载器

委托模型机制

碰到一个类需要加载时,java是如何区分一个类该由哪个类加载器来完成呢? 这里java采用了委托模型机制,就是“类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果Parent 找不到,那么才由自己依照自己的搜索路径搜索类”

如下所示

public class Test {

    public static void main(String[] arg) {

        ClassLoader c = Test.class.getClassLoader();  //获取Test类的类加载器

        System.out.println(c);

        ClassLoader c1 = c.getParent();  //获取c这个类加载器的父类加载器

        System.out.println(c1);

        ClassLoader c2 = c1.getParent();//获取c1这个类加载器的父类加载器

        System.out.println(c2);
    }
}

#输出
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@6fffcba5
null
#Test是由AppClassLoader加载器加载的,AppClassLoader的Parent 加载器是 ExtClassLoader,
#但是ExtClassLoader的Parent为 null 是因为 Loader是用C++语言写的,依java的观点来看,逻辑上并不存在Bootstrap Loader的类实体

类装载器ClassLoader(一个抽象类)描述一下JVM加载class文件的原理机制

  1. 装载:查找和导入Class文件
  2. 链接:其中解析步骤是可以选择的
  • 检查:检查载入的class文件数据的正确性
  • 准备:给类的静态变量分配存储空间
  • 解析:将符号引用转成直接引用
  1. 初始化:对静态变量,静态代码块执行初始化工作

自定义定义ClassLoader

  1. 继承java.lang.ClassLoader
  2. 重写父类的findClass方法

JDK在loadClass方法中帮我们实现了ClassLoader搜索类的算法,当在loadClass方法中搜索不到类时,loadClass方法就会调用findClass方法来搜索类,所以我们只需重写该方法即可。如没有特殊的要求,一般不建议重写loadClass搜索类的算法

类加载器与Web容器

对于运行在 Java EE容器中的 Web 应用来说,类加载器的实现方式与一般的 Java 应用有所不同。以 Apache Tomcat 来说,每个 Web 应用都有一个对应的类加载器实例。该类加载器也使用代理模式,所不同的是它是首先尝试去加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。这是 Java Servlet 规范中的推荐做法,其目的是使得 Web 应用自己的类的优先级高于 Web 容器提供的类。这种代理模式的一个例外是:Java 核心库的类是不在查找范围之内的。这也是为了保证 Java 核心库的类型安全。

java多线程编程

java集合类

点赞(0) 阅读(199) 举报
目录
标题