JAVA 不同类加载器命名空间的理解
2014-11-05 01:25
295 查看
以前一直有这样一个疑惑:
都说在JAVA中,由不同类加载器加载的类在虚拟机中位于不同的命名空间下,不同命名空间下的类相互不可见。
这让我产生了一个迷惑:如果有一个类A使用了java.util.List类,为什么在运行时会没有错误。因为按照类加载的双亲委派机制,自己写的类A一般由系统类加载器加载,而java.util.List肯定是由启动类加载器(也叫Root类加载器)加载的,所以这两个类应该不在一个命名空间下。那在运行时为什么类A还 是能访问到java.util.List?
现在搞明白了,原因如下:
首先我们明白,每一个JAVA类经过加载后,在虚拟机中都有一个对应的类型。
再有以下概念:如果类A被系统类加载器加载,那么该系统类加载器就是此A在虚拟机中对应类型的初始类加载器
Java虚拟机为每个类加载器维护了一个表,其中记录了将该类加载器作为初始类加载器的所有类型。在加载一个类时,虚拟机使用这些列表来决定是否一个类已经被特定的类加载器加载过了(如果该类型在当前类加载器的列表中,就说明已经加载过了,就不再加载)。
再回到刚到A使用java.util.List的例子,当A被加载后,解析到A使用了List,就会请求加载java.util.List。根据类的加载原理及双亲委派机制。会先请类A的类加载器,即系统类加载器加载java.util.List,系统类当然加载不了这个List,所以它会委派给自己的父加载器,即扩展类加载器;同理,最终会由根据类加载器加载这个java.util.List,并成功返回。
根据Java虚拟机规范规定,在这个过程中涉及的所有类加载器--即从系统类加载器到根类加载器间,参与过加载的,都被标记为该类型的初始类加载器。换句话说,java虚拟机为在第一个类加载器维护的表中添加一个类型,用来标明此加载器是该类型的初始类加载器。
这样就不难理解类A为何可以使用java.util.List。尽管它们不是由一个加载器加载的,因为在系统类加载器的表中,即维护了类型A,也维护了类型List。
都说在JAVA中,由不同类加载器加载的类在虚拟机中位于不同的命名空间下,不同命名空间下的类相互不可见。
这让我产生了一个迷惑:如果有一个类A使用了java.util.List类,为什么在运行时会没有错误。因为按照类加载的双亲委派机制,自己写的类A一般由系统类加载器加载,而java.util.List肯定是由启动类加载器(也叫Root类加载器)加载的,所以这两个类应该不在一个命名空间下。那在运行时为什么类A还 是能访问到java.util.List?
现在搞明白了,原因如下:
首先我们明白,每一个JAVA类经过加载后,在虚拟机中都有一个对应的类型。
再有以下概念:如果类A被系统类加载器加载,那么该系统类加载器就是此A在虚拟机中对应类型的初始类加载器
Java虚拟机为每个类加载器维护了一个表,其中记录了将该类加载器作为初始类加载器的所有类型。在加载一个类时,虚拟机使用这些列表来决定是否一个类已经被特定的类加载器加载过了(如果该类型在当前类加载器的列表中,就说明已经加载过了,就不再加载)。
再回到刚到A使用java.util.List的例子,当A被加载后,解析到A使用了List,就会请求加载java.util.List。根据类的加载原理及双亲委派机制。会先请类A的类加载器,即系统类加载器加载java.util.List,系统类当然加载不了这个List,所以它会委派给自己的父加载器,即扩展类加载器;同理,最终会由根据类加载器加载这个java.util.List,并成功返回。
根据Java虚拟机规范规定,在这个过程中涉及的所有类加载器--即从系统类加载器到根类加载器间,参与过加载的,都被标记为该类型的初始类加载器。换句话说,java虚拟机为在第一个类加载器维护的表中添加一个类型,用来标明此加载器是该类型的初始类加载器。
这样就不难理解类A为何可以使用java.util.List。尽管它们不是由一个加载器加载的,因为在系统类加载器的表中,即维护了类型A,也维护了类型List。
相关文章推荐
- Spring JAVA 不同类加载器命名空间的理解
- JAVA 不同类载入器命名空间的理解
- PHP中的use、命名空间、引入类文件、自动加载类的理解
- PHP 命名空间加载的理解
- php 命名空间 和 自动加载机制 的简单理解
- PHP中的use、命名空间、引入类文件、自动加载类的理解
- PHP类的自动加载与命名空间及use的理解
- PHP中的use、命名空间、引入类文件、自动加载类的理解
- java 命名空间 命名规则第1/2页
- 关于模板特化在不同的命名空间的问题
- Struts2使用命名空间后JSP页面无法加载javascript脚本的问题
- Java的类装载器(Class Loader)和命名空间(NameSpace)
- 不同命名空间的相同变量
- expdp、impdp导入导出到不同的表空间、重新命名表
- java的包和.net 的命名空间
- 未能加载类型"命名空间.类"分析
- 修改提交的路径后缀名,不同命名空间跳转,避免重复提交token
- Java的类装载器(Class Loader)和命名空间(NameSpace)
- 理解JNDI中 java:comp/env/jdbc/datasource 与 jdbc/datasource 的不同之处
- Java的类装载器和命名空间