知识大全 Java的类装载器和命名空间
Posted 空间
篇首语:亦余心之所善兮,虽九死其犹未悔。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java的类装载器和命名空间相关的知识,希望对你有一定的参考价值。
Java的类装载器和命名空间 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
摘要 Java的类装载器是Java动态性的核心 本文将向大家简要介绍Java的类装载器 及相关的parent delegation模型 命名空间 运行时包等概念 同时讨论一些在学习中容易混淆的问题
类装载器的功能及分类
顾名思义 类装载器是用来把类(class)装载进JVM的 JVM规范定义了两种类型的类装载器 启动类装载器(bootstrap)和用户自定义装载器(user defined class loader)
bootstrap是JVM自带的类装载器 用来装载核心类库 如java lang *等 如java lang Object是由bootstrap装载的
Java提供了抽象类ClassLoader 所有用户自定义类装载器都实例化自ClassLoader的子类 System Class Loader是一个特殊的用户自定义类装载器 由JVM的实现者提供 在编程者不特别指定装载器的情况下默认装载用户类 系统类装载器可以通过ClassLoader getSystemClassLoader() 方法得到例 测试你所使用的JVM的ClassLoader
/*LoaderSample java*/public class LoaderSample public static void main(String[] args) Class c; ClassLoader cl;
cl = ClassLoader getSystemClassLoader(); System out println(cl);
while (cl != null) cl = cl getParent(); System out println(cl); try c = Class forName( java lang Object ); cl = c getClassLoader(); System out println( java lang Object s loader is + cl); c = Class forName( LoaderSample ); cl = c getClassLoader(); System out println( LoaderSample s loader is + cl); catch (Exception e) e printStackTrace();
在我的机器上(Sun Java )的运行结果C:\\java>java LoaderSample sun misc Launcher$AppClassLoader@ ba sun misc Launcher$ExtClassLoader@ e nulljava lang Object s loader is nullLoaderSample s loader is sun misc Launcher$AppClassLoader@ ba
第一行表示 系统类装载器实例化自类sun misc Launcher$AppClassLoader
第二行表示 系统类装载器的parent实例化自类sun misc Launcher$ExtClassLoader
第三行表示 系统类装载器parent的parent为bootstrap
第四行表示 核心类java lang Object是由bootstrap装载的
第五行表示 用户类LoaderSample 是由系统类装载器装载的
parent delegation模型
从 版本开始 Java引入了双亲委托模型 从而更好的保证Java平台的安全 在此模型下 当一个装载器被请求装载某个类时 它首先委托自己的parent去装载 若parent能装载 则返回这个类所对应的Class对象 若parent不能装载 则由parent的请求者去装载
如图 所示 loader 的parent为loader loader 的parent为system class loader 假设loader 被要求装载类MyClass 在parent delegation模型下 loader 首先请求loader 代为装载 loader 再请求系统类装载器去装载MyClass 若系统装载器能成功装载 则将MyClass所对应的Class对象的reference返回给loader loader 再将reference返回给loader 从而成功将类MyClass装载进虚拟机 若系统类装载器不能装载MyClass loader 会尝试装载MyClass 若loader 也不能成功装载 loader 会尝试装载 若所有的parent及loader 本身都不能装载 则装载失败
若有一个能成功装载 实际装载的类装载器被称为定义类装载器 所有能成功返回Class对象的装载器(包括定义类装载器)被称为初始类装载器 如图 所示 假设loader 实际装载了MyClass 则loader 为MyClass的定义类装载器 loader 和loader 为MyClass的初始类装载器
图 parent delegation模型
需要指出的是 Class Loader是对象 它的父子关系和类的父子关系没有任何关系 一对父子loader可能实例化自同一个Class 也可能不是 甚至父loader实例化自子类 子loader实例化自父类 假设MyClassLoader继承自ParentClassLoader 我们可以有如下父子loader
ClassLoader loader = new MyClassLoader(); //参数 loader 为 parent ClassLoader loader = new ParentClassLoader(loader );
那么parent delegation模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类 从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码 实际上 类装载器的编写者可以自由选择不用把请求委托给parent 但正如上所说 会带来安全的问题
命名空间及其作用
每个类装载器有自己的命名空间 命名空间由所有以此装载器为初始类装载器的类组成 不同命名空间的两个类是不可见的 但只要得到类所对应的Class对象的reference 还是可以访问另一命名空间的类
例 演示了一个命名空间的类如何使用另一命名空间的类 在例子中 LoaderSample 由系统类装载器装载 LoaderSample 由自定义的装载器loader负责装载 两个类不在同一命名空间 但LoaderSample 得到了LoaderSample 所对应的Class对象的reference 所以它可以访问LoaderSampl 中公共的成员(如age)
例 不同命名空间的类的访问
/*LoaderSample java*/import *;import java lang reflect *;public class LoaderSample public static void main(String[] args) try String path = System getProperty( user dir ); URL[] us = new URL( file:// + path + /sub/ ); ClassLoader loader = new URLClassLoader(us); Class c = loader loadClass( LoaderSample ); Object o = c newInstance(); Field f = c getField( age ); int age = f getInt(o); System out println( age is + age); catch (Exception e) e printStackTrace();
/*sub/Loadersample java*/public class LoaderSample static System out println( LoaderSample loaded ); public int age = ;
编译 javac LoaderSample java; javac sub/LoaderSample java
运行 java LoaderSample
LoaderSample loaded age is
从运行结果中可以看出 在类LoaderSample 中可以创建处于另一命名空间的类LoaderSample 中的对象并可以访问其公共成员age
运行时包(runtime package)
由同一类装载器定义装载的属于相同包的类组成了运行时包 决定两个类是不是属于同一个运行时包 不仅要看它们的包名是否相同 还要看类装载器是否相同 只有属于同一运行时包的类才能互相访问包可见的类和成员 这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况 假设用户自己定义了一个类java lang Yes 并用用户自定义的类装载器装载 由于java lang Yes和核心类库java lang *由不同的装载器装载 它们属于不同的运行时包 所以java lang Yes不能访问核心类库java lang中类的包可见的成员
总结
cha138/Article/program/Java/hx/201311/27180相关参考
C#高级编程:使用XPath命名空间中的类[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&n
Java类使用类装载器实现装载文件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! viewpla
关于包的祥解: 概念: 包(Package)是Java编程的基础包蕴涵于标准类的体系结构和用户自己的程序中包是有唯一命名 的类的集合 给自己的类打包: 在打包之前我们最好先定义一
知识大全 java设计模式之 Adapter(纠合不兼容的类)
java设计模式之Adapter(纠合不兼容的类) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
简述 众所周知javaexe是javaclass文件的执行程序但实际上javaexe程序只是 一个执行的外壳它会装载jvmdll(windows下以下皆以windows平台为例 linu
.Net开发漫谈:关于命名空间和目录划分 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 从命名空
Java编程风格与命名规范整理 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 基本命名规范 包
新手入门之VisualC#命名空间详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 命名空间提
PHP5.3特性:命名空间 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! PHP的一个新的重要特
.NET程序集与命名空间 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 程序集 程序集(ass