欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识
原文出处: 五月的仓颉

类与类加载

虚拟机设计团队把类加载阶段张的”通过一个类的全限命名来获取此类的二进制字节约”这个行动放到Java虚拟机外部去实现,以便让应用措施本身抉择如何去获取所需要的类。实现这个行动的代码模块称为”类加载器”。类加载器固然只用于实现类的加载行动,但它在Java措施中起到的浸染却远远不限定于类加载阶段。对付任意一个类,都需要由加载它的类加载器和这个类自己一同确立其在Java虚拟机中的独一性,每一个类加载器,都拥有一个独立的类名称空间。这句话表达地再简朴一点就是:较量两个类是否”相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,不然纵然这两个类来历于同一个.class文件,被同一个虚拟机加载,只要加载它们的类加载器差异,这两个类肯定不相等。

上面说的”相等”,包罗代表类的.class工具的equals()要领、isAssignableFrom()要领、isInstance()要领的返回功效,也包罗利用instanceof要害字做工具所属干系鉴定等环境。

类加载器模子

从Java虚拟机的角度讲,只有两种差异的类加载器:启动类加载器Bootstrap ClassLoader,这个类加载器是由C++语言实现的,是虚拟机自身的一部门;其他类加载器,这些类加载器都由Java语言实现,独立于虚拟机外部,而且全部担任自java.lang.ClassLoader。从开拓人员的角度讲,类加载器还可以分别地越发细致一些,一张图就能说明:

那系统中将会呈现<a href=劳务调派信息打点系统 多个差异的Object类" src="http://www.importnew.com/https:/images2015.cnblogs.com/blog/801753/201509/801753-20150928224102605-1436171001.png" />

关于这张图首先说两点:

1、这三个条理的类加载器并不是担任干系,而只是条理上的界说

2、它并不是一个强制性的约束模子,而是Java设计者推荐给开拓者的一种类加载器实现方法

OK,然后一个一个类加载器来看:

1、启动类加载器Bootstrap ClassLoader

之前说过了这是一个嵌在JVM内核中的加载器。它认真加载的是JAVA_HOME/lib下的类库,系统类加载器无法被Java措施直策应用

2、扩展类加载器Extension ClassLoader

这个类加载器由sun.misc.Launcher$ExtClassLoader实现,它认真用于加载JAVA_HOME/lib/ext目次中的,可能被java.ext.dirs系统变量指定所指定的路径中所有类库,开拓者可以直接利用扩展类加载器。java.ext.dirs系统变量所指定的路径的可以通过措施来查察

public class TestMain
{
    public static void main(String[] args)
    {
        System.out.println(System.getProperty("java.ext.dirs"));
    }
}

运行功效

E:\MyEclipse10\Common\binary\com.sun.java.jdk.win32.x86_64_1.6.0.013\jre\lib\ext;C:\Windows\Sun\Java\lib\ext

3、应用措施类加载器Application ClassLoader

这个类加载器由sun.misc.Launcher$AppClassLoader实现。这个类也一般被称为系统类加载器,写个小措施看下:

public class TestMain
{
    public static void main(String[] args)
    {
        System.out.println(ClassLoader.getSystemClassLoader());
    }
}

运行功效为:

sun.misc.Launcher$AppClassLoader@546b97fd

看到通过”ClassLoader.getSystemClassLoader”,获得的是sun.misc.Launcher$AppClassLoader,这也证明白JDK认为Application ClassLoader是系统类加载器。顺便按照类加载器模子,打印一下这个类的父加载器:

public class TestMain
{
    public static void main(String[] args)
    {
        System.out.println(ClassLoader.getSystemClassLoader().getParent());
    }
}

运行功效为:

sun.misc.Launcher$ExtClassLoader@535ff48b

看出Application ClassLoader的父加载器确实是Extension ClassLoader,切合图中的模子。那么再打印父加载器呢?凭据我们的想法应该是Bootstrap ClassLoader了,看下是不是:

public class TestMain
{
    public static void main(String[] args)
    {
        System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());
    }
}

运行功效为:

null

这会打印出来的是null了。其实也很好领略,Bootstrap ClassLoader以外的ClassLoader都是Java实现的,因此这些ClassLoader势必在Java堆中有一份实例在,所以Extension ClassLoader和Application ClassLoader都能打印出内容来。可是Bootstrap ClassLoader是JVM的一部门,是用C/C++写的,不属于Java,昆山软件公司,自然在Java堆中也没有本身的空间,所以就返回null了。所以,假如ClassLoader获得的是null,那么暗示的ClassLoader就是Bootstrap ClassLoader。