- 浏览: 369257 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
tuspark:
关于javadoc这里讲解的更全面:《javadoc设置》。
Eclipse中生成javadoc【Z】 -
yuexiang1007:
帮我解决了问题,谢谢!!!
java.math.BigInteger使用心得总结 -
netwelfare:
个人感觉,文章对HashMap的遍历分析的有点浅,不如这里的介 ...
HashMap遍历的两种方式【Z】 -
memoryisking:
关于java.math.BigInteger讲解在这里可以看到 ...
java.math.BigInteger使用心得总结 -
巴尾的兔兔帅:
divide应该是除吧?不是减。dividepublic Bi ...
java.math.BigInteger使用心得总结
JVM规范定义了两种类型的类装载器:启动内装载器
(bootstrap)
和用户自定义装载器
(user-defined class loader)
。
一.
ClassLoader
基本概念
1
.
ClassLoader
分类
类装载器是用来把类(class)装载进JVM的。
JVM规范定义了两种类型的类装载器:启动内装载器
(bootstrap)
和用户自定义装载器
(user-defined class loader)
。
JVM在运行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader.
Bootstrap是用C++编写的,我们在Java中看不到它,是null,是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。
AppClassLoader
的
Parent
是
ExtClassLoader
,而
ExtClassLoader
的
Parent
为
Bootstrap ClassLoader
。
Java
提供了抽象类
ClassLoader
,所有用户自定义类装载器都实例化自
ClassLoader
的子类。
System Class Loader
是一个特殊的用户自定义类装载器,由
JVM
的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类
。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
例1,测试你所使用的JVM的ClassLoader
/*LoaderSample1.java*/
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( " LoaderSample1 " );
cl = c.getClassLoader();
System.out.println( " LoaderSample1's loader is " + cl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
在我的机器上(Sun Java 1.4.2)的运行结果
sun.misc.Launcher$AppClassLoader@1a0c10f
sun.misc.Launcher$ExtClassLoader@e2eec8
null
java.lang.Object's loader is null
LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@1a0c10f
第一行表示,系统类装载器实例化自类sun.misc.Launcher$AppClassLoader
第二行表示,系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
第三行表示,系统类装载器parent的parent为bootstrap
第四行表示,核心类java.lang.Object是由bootstrap装载的
第五行表示,用户类LoaderSample1是由系统类装载器装载的
二.
parent delegation模型
从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的
parent
去装载,若
parent
能装载,则返回这个类所对应的
Class
对象,若
parent
不能装载,则由
parent
的请求者去装载
。
图 1 parent delegation模型
如
图1所示,loader2的parent为loader1,loader1的parent为system class
loader。假设loader2被要求装载类MyClass,在parent
delegation模型下,loader2首先请求loader1代为装载,loader1再请求系统类装载器去装载MyClass。若系统装载器能成
功装载,则将MyClass所对应的Class对象的reference返回给loader1,loader1再将reference返回给
loader2,从而成功将类MyClass装载进虚拟机。若系统类装载器不能装载MyClass,loader1会尝试装载MyClass,若
loader1也不能成功装载,loader2会尝试装载。若所有的parent及loader2本身都不能装载,则装载失败。
若有一
个能成功装载,实际装载的类装载器被称为定义类装载器,所有能成功返回Class对象的装载器(包括定义类装载器)被称为初始类装载器。如图1所示,假设
loader1实际装载了MyClass,则loader1为MyClass的定义类装载器,loader2和loader1为MyClass的初始类装
载器。
需要指出的是,Class Loader是对象,它的父子关系和类的父子关系没有任何关系。
那么parent delegation模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类,从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码。实际上,类装载器的编写者可以自由选择不用把请求委托给
parent
,但正如上所说,会带来安全的问题。
三.命名空间及其作用
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
例
2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装
载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的
reference,所以它可以访问LoaderSampl3中公共的成员(如age)。
例2不同命名空间的类的访问
/*LoaderSample2.java*/
import java.lang.reflect. * ;
public class LoaderSample2 {
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( " LoaderSample3 " );
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/Loadersample3.java*/
static {
System.out.println( " LoaderSample3 loaded " );
}
public int age = 30 ;
}
编译:javac LoaderSample2.java; javac sub/LoaderSample3.java
运行:java LoaderSample2
LoaderSample3 loaded
age is 30
从运行结果中可以看出,在类LoaderSample2中可以创建处于另一命名空间的类LoaderSample3中的对象并可以访问其公共成员age。
运行时包(runtime package)
由
同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相
同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自
己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装
载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。
总结
命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了
Java
的安全,运行时包增加了对包可见成员的保护。
二.
扩展ClassLoader
方法
我们目的是从本地文件系统使用我们实现的类装载器装载一个类。为了创建自己的类装载器我们应该扩展
ClassLoader
类,这是一个抽象类。我们创建一个
FileClassLoader extends ClassLoader
。我们需要覆盖
ClassLoader
中的
findClass(String name)
方法,这个方法通过类的名字而得到一个
Class
对象。
{
byte [] data = loadClassData(name);
return defineClass(name, data, 0 , data.length);
}
我们还应该提供一个方法loadClassData(String name),通过类的名称返回class文件的字
节数组。然后使用ClassLoader提供的defineClass()方法我们就可以返回Class对象了。
{
FileInputStream fis = null ;
byte [] data = null ;
try
{
fis = new FileInputStream( new File(drive + name + fileType));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int ch = 0 ;
while ((ch = fis.read()) != - 1 )
{
baos.write(ch);
}
data = baos.toByteArray();
} catch (IOException e)
{
e.printStackTrace();
}
return data;
}
发表评论
-
JSTL中的<c:标签【Z】
2011-08-31 20:48 1146Taglib 伪指令 Java代码 ... -
java接口嵌套【Z】
2011-05-18 17:09 1342在Java语言中,接口可以嵌套在类或其它接口中。由于Jav ... -
JMF安装【Z】
2011-05-07 20:52 1094下载并安装JMF 在MyEclipse中选择 窗口/首选项/ ... -
javaMail【Z】
2011-04-18 16:12 1078commons-email-1.1.jar: 这是Apache ... -
java生成PDF文件【Z】
2011-01-14 15:03 1211如果应用程序需要动态 ... -
字符集编码【Z】
2010-12-29 18:54 893问题研究 --字符集 ... -
java常用第三方jar包【Z】
2010-12-26 22:39 3360commons-digester.jar Digeste ... -
不使用JNI获得系统信息【Z】
2010-12-22 13:28 589在Java中,可以获得总的物理内存、剩余的物理内存、已使用的物 ... -
java获得当前路径【Z】
2010-12-18 14:37 9421、利用System.getProperty()函数获取当前路 ... -
java容器类-1【Z】
2010-12-17 21:43 1013对象的集合 如果程序的对象数量有限 ... -
java UIManager的风格【Z】
2010-12-17 12:28 2671Java'中的几种Look and Feel 1、Met ... -
serialVersionUID的作用和意义【Z】
2010-12-15 10:38 1553在Java中,软件的兼容性是一个大问题,尤其在使用到对象串行性 ... -
HashMap遍历的两种方式【Z】
2010-12-07 18:42 968HashMap遍历的两种方式 ... -
23个经典JDK设计模式——系统JDK使用设计模式的例子【Z】
2010-12-05 21:33 1029酷壳 版主陈皓近日发表博文《JDK里的设计模式 》,文中他 ... -
String/StringBuffer/StringBuild【Z】
2010-11-12 14:10 1346[编辑] String,StringBuffer和String ... -
tomcat中web.xml详解【Z】
2010-10-18 14:47 9251 定义头和根元素 部 ... -
Java 理论与实践: 线程池与工作队列【Z】
2010-10-18 09:45 932线程池有助于实现最 ... -
单例模式完全剖析【Z】
2010-10-17 22:48 790Buildfile: build.xml ... -
在MyEclipse中直接查看class文件(在没有源码的情况下)【Z】
2010-10-17 22:04 1309想直接在myeclipse中查看class文件,就像查看普通的 ... -
HashMap实现及冲突【Z】
2010-10-12 21:41 962了解 HashMap 原理对于日后的缓存机制多少有 ...
相关推荐
在Java编程语言中,ClassLoader是核心的组成部分,它负责加载类到JVM(Java虚拟机)中。`ClassLoaderDemo.7z`这个压缩包提供的示例,旨在帮助我们理解ClassLoader的工作原理,特别是双亲委托模型以及如何打破这个...
本示例项目"my_classloader_demo-master.7z"聚焦于通过Native层实现热修复,这涉及到Android系统的核心组件以及对Java虚拟机(JVM)的深入理解。 1. **类加载器(ClassLoader)**: 在Java编程中,类加载器是负责将类...
最后,使用`ClassLoader`加载生成的字节码,使其在JVM中生效。 总的来说,BCEL是一个强大的工具,它为Java开发者提供了一种直接操作字节码的途径,极大地扩展了Java编程的可能性。无论是进行代码分析、动态生成还是...
- 类加载机制:Bootstrap ClassLoader、Extension ClassLoader、AppClassLoader。 - 获取类信息:Class类,Class.forName(),newInstance()。 - 动态调用方法和访问字段:Method、Constructor、Field。 8. **...
了解类加载器(如Bootstrap、Extension和Application ClassLoader)的工作原理,可以更好地管理类路径和库依赖。 #### 6. 多线程编程 掌握线程生命周期、同步机制(如synchronized关键字和Lock接口)、线程通信(如...
SimpleDateFormat formatter = new SimpleDateFormat("EEE,d MMM yyyy HH:mm:ss:SSS Z"); System.out.println("start:" + formatter.format(d1)); System.out.println("" + str.length() + "字符过滤后" + ...
at java.lang.ClassLoader$NativeLibrary.load(Native Method) /******************************/ 解决方法 /*****************************/ 将tomcat目录下的bin文件中的tcnative-1.dll文件替换为64位
在Java编程语言中,类的实例化是一个关键概念,它涉及到如何创建对象并分配内存空间。今天我们将深入探讨Java中类的实例化步骤,特别是与`static`关键字相关的部分。 首先,`static`关键字在Java中有着特殊的意义,...
**BaseDexClassLoader**是Android中的一个核心类,它继承自Java的`ClassLoader`,负责加载应用的 Dalvik 或 ART 字节码(即.dex文件)。在Android 28(对应的是Android 9.0 Pie)版本中,这个类用于处理应用程序的类...
7. **类加载器(ClassLoader)**:了解"sun"包中的类加载器实现,可以深入理解Java的类加载过程,包括双亲委派模型和自定义类加载器的实现。 8. **并发(Concurrency)**:"sun"包中的并发工具类源码展示了Java如何...
10. **类加载机制**:JDK11的类加载机制仍然遵循“双亲委派模型”,源码中的`java.lang.ClassLoader`类及其子类展示了如何加载和查找类。 通过深入研究JDK11源码,开发者不仅可以了解到Java语言的最新发展,还能...
3. **用户界面**:在需要按首字母筛选的界面(如联系人列表)中,可以通过这个库将汉字姓名转换为拼音,以便进行A到Z的导航。 4. **国际化**:对于支持多种语言的应用,尤其是需要与英文界面集成时,拼音转换可以...
类加载主要由ClassLoader及其子类负责,它们动态地将.class文件加载到内存。加载方式有隐式加载(如new关键字创建对象时)和显式加载(如通过class.forName())。JVM按需加载,仅加载必要的类,提高了速度并减少了...
- **ClassLoader**:是Java虚拟机(JVM)中负责加载类文件的机制。在Android中,通过自定义ClassLoader可以实现动态加载DEX文件,即Android应用程序的主要执行文件。这种方式虽然可以实现动态加载,但是在未来的版本...
- 类加载器负责加载类到JVM,包括Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader。 - 自定义类加载器可以实现特定的加载逻辑,比如热部署。 7. **方法区** - 存储类的信息,如常量池、字段和...