- 浏览: 1595047 次
- 性别:
文章分类
- 全部博客 (2929)
- 非技术 (18)
- Eclipse (11)
- JAVA (31)
- 正则表达式 (0)
- J2EE (4)
- DOS命令 (2)
- WEB前端 (52)
- JavaScript (69)
- 数据库 (8)
- 设计模式 (0)
- JFreechart (1)
- 操作系统 (1)
- 互联网 (10)
- EasyMock (1)
- jQuery (5)
- Struts2 (12)
- Spring (24)
- 浏览器 (16)
- OGNL (1)
- WebService (12)
- OSGi (14)
- 软件 (10)
- Tomcat (2)
- Ext (3)
- SiteMesh (2)
- 开源软件 (2)
- Hibernate (2)
- Quartz (6)
- iBatis (2)
最新评论
1.Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,
类装载器所做的工作实质是把类文件从硬盘读取到内存中
2.java中的类大致分为三种:
1.系统类
2.扩展类
3.由程序员自定义的类
3.类装载方式,有两种
1.隐式装载, 程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中,
2.显式装载, 通过class.forname()等方法,显式加载需要的类
隐式加载与显式加载的区别:
两者本质是一样?,
?
4.类加载的动态性体现
一个应用程序总是由n多个类组成,Java程序启动时,并不是一次把所有的类全部加载后再
运行,它总是先把保证程序运行的基础类一次性加载到jvm中,其它类等到jvm用到的时候再加载,这样的好处是节省了内存的开销,因为java最早就是为嵌入式系统而设计的,内存宝贵,这是一种可以理解的机制,而用到时再加载这也是java动态性的一种体现
5.java类装载器
Java中的类装载器实质上也是类,功能是把类载入jvm中,值得注意的是jvm的类装载器并不是一个,而是三个,层次结构如下:
Bootstrap Loader - 负责加载系统类
|
- - ExtClassLoader - 负责加载扩展类
|
- - AppClassLoader - 负责加载应用类
为什么要有三个类加载器,一方面是分工,各自负责各自的区块,另一方面为了实现委托模型,下面会谈到该模型
6. 类加载器之间是如何协调工作的
前面说了,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);
}
}
把以上代码存到d:/my 文件夹下,直接编译,然后在dos模式下运行
D:/my/java Test
。。。AppClassLoader。。。
。。。ExtClassLoader。。。
Null
D:/my
注: 。。。表示省略了内容
可以看出Test是由AppClassLoader加载器加载的
AppClassLoader的Parent 加载器是 ExtClassLoader
但
是ExtClassLoader的Parent为 null 是怎么回事呵,朋友们留意的话,前面有提到Bootstrap
Loader是用C++语言写的,依java的观点来看,逻辑上并不存在Bootstrap
Loader的类实体,所以在java程序代码里试图打印出其内容时,我们就会看到输出为null
【注:以下内容大部分引用java深度历险】
弄明白了上面的示例,接下来直接进入类装载的委托模型实例,写两个文件,如下:
文件:Test1.java
Public class Test1{
Public static void main(String[] arg){
System.out.println(Test1.class.getClassLoader());
Test2 t2 = new Test2();
T2.print();
}
}
文件: Test2.java
Public class Test2{
Public void prin(){
System.out.println(this.getClass().getClassLoader());
}
}
这
两个类的作用就是打印出载入它们的类装载器是谁, 将这两个文件保存到d:/my目录下,编译后,我们在复制两份,分别置于
<JRE所在目录>/classes下(注意,刚开始我们的系统下没有此目录,需自己建立) 与
<JRE所在目录>/lib/ext/classes下(同样注意,开始我们的系统下也没此目录,手工建立),
然后切换到d:/my目录下开始测试,
测试一:
<JRE所在目录>/classes下
Test1.class
Test2.class
<JRE所在目录>/lib/ext/classes下
Test1.class
Test2.class
D:/my下
Test1.class
Test2.class
dos下输入运行命令,结果如下:
D:/my>java Test1
Null
Null
D:/my>
从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载
入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class. 由于
<JRE所在目录>/Classes目录为Bootstrap Loader的搜索路径之一,所以Bootstrap
Loader找到了Test1.class,因此将它载入,接着在Test1.class之内有载入Test2.class的需求,由于
Test1.class是由Bootstrap Loader所载入,所以Test2.class内定是由Bootstrap
Loader根据其搜索路径来找,因Test2.class也位于Bootstrap
Loader可以找到的路径下,所以也被载入了,最后我们看到Test1.class与Test2.class都是由Bootstrap
Loader(null)载入。
测试二:
<JRE所在目录>/classes下
Test1.class
<JRE所在目录>/lib/ext/classes下
Test1.class
Test2.class
D:/my下
Test1.class
Test2.class
dos下输入运行命令,结果如下:
D:/my>java Test1
Null
Exception in thread “main” java.lang.NoClassdefFoundError:Test2 at Test1.main。。。
D:/my>
从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载
入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class. 由于
<JRE所在目录>/Classes目录为Bootstrap Loader的搜索路径之一,所以Bootstrap
Loader找到了Test1.class,因此将它载入,接着在Test1.class之内有载入Test2.class的需求,由于
Test1.class是由Bootstrap Loader所载入,所以Test2.class内定是由Bootstrap
Loader根据其搜索路径来找,但是因为Bootstrap Loader根本找不到Test2.class(被我们删除了),而Bootstrap
Loader又没有Parent,所以无法载入Test2.class.最后我们看到Test1.class是由Bootstrap
Loader(null)载入,而Test2.class则无法载入
测试三
<JRE所在目录>/classes下
Test2.class
<JRE所在目录>/lib/ext/classes下
Test1.class
Test2.class
D:/my下
Test1.class
Test2.class
dos下输入运行命令,结果如下:
D:/my>java Test1
。。。ExtClassLoader。。。
Null
D:/my>
从输出结果我们可以看出,当AppClassLoader要载入Test1.class时,先请其Parent,也就是ExtClassLoader来载
入,而ExtclassLoader又请求其Parent,即Bootstrap Loader来载入Test1.class.但是Bootstrap
Loader无法在其搜索路径下找到Test1.class(被我们删掉了),所以ExtClassLoader只得自己搜索,因此
ExtClassLoader在其搜索路径
<JRE所在目录>/lib/ext/classes下找到了Test1.class,因此将它载入,接着在Test1.class之内有载
入Test2.class的需求,由于Test1.class是由ExtClassLoader所载入,所以Test2.class内定是由
ExtClassLoader根据其搜索路径来找,但是因为ExtClassLoader有Parent,所以先由Bootstrap
Loader帮忙寻找,Test2.class位于Bootstrap Loader可以找到的路径下,所以被Bootstrap
Loader载入了.最后我们看到Test1.class是由ExtClassLoader载入,而Test2.class则是由Bootstrap
Loader(null)载入
了解了以上规则,请朋友们自行分析以下场景的执行结果
测试四:
<JRE所在目录>/classes下
<JRE所在目录>/lib/ext/classes下
Test1.class
Test2.class
D:/my下
Test1.class
Test2.class
测试五:
<JRE所在目录>/classes下
<JRE所在目录>/lib/ext/classes下
Test1.class
D:/my下
Test1.class
Test2.class
测试六:
<JRE所在目录>/classes下
<JRE所在目录>/lib/ext/classes下
Test2.class
D:/my下
Test1.class
Test2.class
测试七:
<JRE所在目录>/classes下
<JRE所在目录>/lib/ext/classes下
D:/my下
Test1.class
Test2.class
以上理解,错漏之处请朋友们及时指出,以免怠误大家
发表评论
-
使用Java 动态代理实现AOP
2009-07-22 14:29 580目前整个开发社区对AOP(Aspect Oriented P ... -
Java中用动态代理类实现记忆功能
2009-07-22 14:30 680记忆是衍生自lisp,python, ... -
JAVA动态代理实现方法
2009-07-22 14:31 664在目前的Java开发包中包含了对动态代理的支持,但是其实现只支 ... -
对代理模式与Java动态代理类的理解(转)
2009-07-22 14:32 7421. 代理模式 代理模式的作用是:为其他对象 ... -
十年与java 相关的名字
2009-07-22 17:12 700RickardOberg:J2EE奇才 文/ ... -
搞懂java中的synchronized关键字
2009-07-28 17:48 578实际上,我关于java的基 ... -
字符串转化为unicode编码
2009-07-31 16:16 859package com.util; import java. ... -
移位运算符的规则及其数学意义
2009-07-31 18:02 728移位运算符就是在二进制的基础上对数字进行平移。按照平移的方 ... -
几个谜题,深入的了解java
2009-08-03 17:02 701在2009年的JavaOne大会上,Joshua Bloch和 ... -
一、我对java中编码的理解(摘)
2009-08-06 09:17 5931. 编码的产生 对电 ... -
四、深入下package,import:(摘)
2009-08-06 09:18 671注:因package,import涉及较多内容,另开一个帖子了 ... -
三、我对java中类路径的理解(摘)
2009-08-06 09:18 500Java中的类路径分“编译后的存放路径” 和 “运行时的查找路 ... -
java class文件格式解析(摘)
2009-08-06 09:19 7601.目的 ... -
关于 JavaBean 规范你还是应该知道的二三事
2009-08-06 09:22 793作为 Java 程序员,对于 JavaBean 也许你会说再熟 ... -
synchronized(this)的几个简单示例
2009-08-06 10:31 782一、当两个并发线程访问同一个对象object中的这个synch ... -
java压缩对象 与 对象的序列化
2009-08-07 17:39 642gzip是目前广泛应用的一种压缩方式,它具有很高的压缩比和压缩 ... -
Java常见问题集锦
2009-08-12 12:22 649如何设置Java 2(JDK1.2)的环境变量? 哪些Jav ... -
JavaFX尝鲜
2009-08-17 17:24 487java6出来以后,其一大 ... -
Java在不同环境下获取当前路径的方法--this.getClass().getResource("")
2009-08-17 17:24 6701. 在Servlet/Filter等Servlet web环 ... -
JAVA进阶:VO(DTO)与PO(DAO)之间的转换
2009-08-26 13:58 833PO即 Persistence Object VO ...
相关推荐
java类装载介绍,介绍了java装载类的先后顺序
Java虚拟机类装载的原理及实现
Java虚拟机类装载111.docJava虚拟机类装载111.docJava虚拟机类装载111.doc
类的动态装载机制是JVM的一...本文介绍了JVM中类装载的原理、实现以及应用,尤其分析了ClassLoader的结构、用途以及如何利用自定义 的ClassLoader装载并执行Java类,希望能使读者对JVM中的类装载有一个比较深入的理解。
简单的介绍和描述Java虚拟机类装载:原理、实现与应用
类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念
主要讲述Java的类装载器和命名空间,ClassLoader/parent delegation模型
本例采用java编写的装载问题,采用的是FIFO队列形式,参考:算法设计与分析
Java虚拟机类装载:原理、实现与应用.doc
摘要通过构建一个能够把Java类装载隔离到一个指定的jar文件中的类装载组件容器框架,你可以确保运行时刻会装载你期望的组件版本。Java的类装载框架强有力且具有灵活性。它允许应用程序存取类库而不必链接到静态的...
它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java Applet 需要从远程下载 Java 类文件到浏览器中并执行。现在类加载器在 ...
Java类装载过程_.docx
类装载器是Java 平台上最神秘,也是最 有趣的一个组,通过类装载器,除了可以实现程序的动态性之外,更能够做 到 无 懈 可 击 的 安 全 性
算法作为计算机专业学生的必修课,同时也是软件开发过程中必备的编程思想,对学习研究计算机专业意义重大;正因为这门课程难,所以除了相关方面的书籍,网络资源少的可怜,尤其是java代码简直如大海捞针。因此,做完...
完整的代码。用java来来写的装载问题。
java jvm类装载器原理 介绍较为详细 大家可以参考
java虚拟机装载类的原理,从基础上描述,让我们更清楚底层的运作
classguard是防止java反编译工具的工具,它允许java类文件使用128bit的AES加密加密。AES密钥是随机生成的每次启动加密工具。解密是一个自定义的类装载器透明地做。这类装载器的主要部分是用C防止反编译等篡改。
invokeMethod.java 同一个类中调用方法示例 invokeOther.java 类的外部调用方法示例 invokeStaticMethod.java 调用静态方法示例 localVariable.java 演示局部变量 localVSmember.java 局部变量与成员变量同名...