- 浏览: 353976 次
- 性别:
- 来自: 珠海
文章分类
最新评论
-
yanxhyxz:
怎么静态化动态文件,如果不使用perl脚本可以实现文件过期吗? ...
通过Nginx架设灵活的网站静态化方案 -
fu_ok:
long subLen = (long) Math.ceil( ...
使用java实现http多线程下载 -
fu_ok:
哇,好厉害,楼主现在还写程序么
使用java实现http多线程下载 -
jimok618:
居然70几条评论里都没提到RandomAccessFile是非 ...
使用java实现http多线程下载 -
hexawing:
其实也不是,在 ruby中,方法实际上就是一个隐式的begin ...
Ruby 异常处理
ClassLoader一个经常出现又让很多人望而却步的词,本文将试图以最浅显易懂的方式来讲解 ClassLoader,希望能对不了解该机制的朋友起到一点点作用。
要深入了解ClassLoader,首先就要知道ClassLoader是用来干什么的,顾名思义,它就是用来加载Class文件到JVM,以供程序使用的。我们知道,java程序可以动态加载类定义,而这个动态加载的机制就是通过ClassLoader来实现的,所以可想而知ClassLoader的重要性如何。
看到这里,可能有的朋友会想到一个问题,那就是既然ClassLoader是用来加载类到JVM中的,那么ClassLoader又是如何被加载呢?难道它不是java的类?
没有错,在这里确实有一个ClassLoader不是用java语言所编写的,而是JVM实现的一部分,这个ClassLoader就是bootstrap classloader(启动类加载器),这个ClassLoader在JVM运行的时候加载java核心的API以满足java程序最基本的需求,其中就包括用户定义的ClassLoader,这里所谓的用户定义是指通过java程序实现的ClassLoader,一个是ExtClassLoader,这个ClassLoader是用来加载java的扩展API的,也就是/lib/ext中的类,一个是AppClassLoader,这个ClassLoader是用来加载用户机器上CLASSPATH设置目录中的Class的,通常在没有指定ClassLoader的情况下,程序员自定义的类就由该ClassLoader进行加载。
当运行一个程序的时候,JVM启动,运行bootstrap classloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。
上面大概讲解了一下ClassLoader的作用以及一个最基本的加载流程,接下来将讲解一下ClassLoader加载的方式,这里就不得不讲一下ClassLoader在这里使用了双亲委托模式进行类加载。
每一个自定义ClassLoader都必须继承ClassLoader这个抽象类,而每个ClassLoader都会有一个parent ClassLoader,我们可以看一下ClassLoader这个抽象类中有一个getParent()方法,这个方法用来返回当前ClassLoader的parent,注意,这个parent不是指的被继承的类,而是在实例化该ClassLoader时指定的一个ClassLoader,如果这个parent为null,那么就默认该ClassLoader的parent是bootstrap classloader,这个parent有什么用呢?
我们可以考虑这样一种情况,假设我们自定义了一个ClientDefClassLoader,我们使用这个自定义的ClassLoader加载java.lang.String,那么这里String是否会被这个ClassLoader加载呢?事实上java.lang.String这个类并不是被这个ClientDefClassLoader加载,而是由bootstrap classloader进行加载,为什么会这样?实际上这就是双亲委托模式的原因,因为在任何一个自定义ClassLoader加载一个类之前,它都会先委托它的父亲ClassLoader进行加载,只有当父亲ClassLoader无法加载成功后,才会由自己加载,在上面这个例子里,因为java.lang.String是属于java核心API的一个类,所以当使用ClientDefClassLoader加载它的时候,该ClassLoader会先委托它的父亲ClassLoader进行加载,上面讲过,当ClassLoader的parent为null时,ClassLoader的parent就是bootstrap classloader,所以在ClassLoader的最顶层就是bootstrap classloader,因此最终委托到bootstrap classloader的时候,bootstrap classloader就会返回String的Class。
我们来看一下ClassLoader中的一段源代码:
从上面一段代码中,我们可以看出一个类加载的大概过程与之前我所举的例子是一样的,而我们要实现一个自定义类的时候,只需要实现findClass方法即可。
为什么要使用这种双亲委托模式呢?
第一个原因就是因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
第二个原因就是考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的ClassLoader。
上面对ClassLoader的加载机制进行了大概的介绍,接下来不得不在此讲解一下另外一个和ClassLoader相关的类,那就是Class类,每个被ClassLoader加载的class文件,最终都会以Class类的实例被程序员引用,我们可以把Class类当作是普通类的一个模板,JVM根据这个模板生成对应的实例,最终被程序员所使用。
我们看到在Class类中有个静态方法forName,这个方法和ClassLoader中的loadClass方法的目的一样,都是用来加载class的,但是两者在作用上却有所区别。
Class<?> loadClass(String name)
Class<?> loadClass(String name, boolean resolve)
我们看到上面两个方法声明,第二个方法的第二个参数是用于设置加载类的时候是否连接该类,true就连接,否则就不连接。
说到连接,不得不在此做一下解释,在JVM加载类的时候,需要经过三个步骤,装载、连接、初始化。装载就是找到相应的class文件,读入JVM,初始化就不用说了,最主要就说说连接。
连接分三步,第一步是验证class是否符合规格,第二步是准备,就是为类变量分配内存同时设置默认初始值,第三步就是解释,而这步就是可选的,根据上面loadClass方法的第二个参数来判定是否需要解释,所谓的解释根据《深入JVM》这本书的定义就是根据类中的符号引用查找相应的实体,再把符号引用替换成一个直接引用的过程。有点深奥吧,呵呵,在此就不多做解释了,想具体了解就翻翻《深入JVM吧》,呵呵,再这样一步步解释下去,那就不知道什么时候才能解释得完了。
我们再来看看那个两个参数的loadClass方法,在JAVA API 文档中,该方法的定义是protected,那也就是说该方法是被保护的,而用户真正应该使用的方法是一个参数的那个,一个参数的loadclass方法实际上就是调用了两个参数的方法,而第二个参数默认为false,因此在这里可以看出通过loadClass加载类实际上就是加载的时候并不对该类进行解释,因此也不会初始化该类。而Class类的forName方法则是相反,使用forName加载的时候就会将Class进行解释和初始化,forName也有另外一个版本的方法,可以设置是否初始化以及设置ClassLoader,在此就不多讲了。
不知道上面对这两种加载方式的解释是否足够清楚,就在此举个例子吧,例如JDBC DRIVER的加载,我们在加载JDBC驱动的时候都是使用的forName而非是ClassLoader的loadClass方法呢?我们知道,JDBC驱动是通过DriverManager,必须在DriverManager中注册,如果驱动类没有被初始化,则不能注册到DriverManager中,因此必须使用forName而不能用loadClass。
通过ClassLoader我们可以自定义类加载器,定制自己所需要的加载方式,例如从网络加载,从其他格式的文件加载等等都可以,其实ClassLoader还有很多地方没有讲到,例如ClassLoader内部的一些实现等等,本来希望能够讲得简单易懂一点,可是结果自己看回头好像感觉并不怎么样,郁闷,看来自己的文笔还是差太多了,希望能够给一些有需要的朋友一点帮助吧。
还是您老高深……
alibubu说得是,我比较同意,我是在百度上搜索“什么时候需要用到ClassLoader”的时候搜索到这个帖子的。我正在看《深入Java虚拟机》,第3章讲了ClassLoader,我看完了觉得有必要弄清楚什么时候需要用到ClassLoader,因为我看了书上写的一大堆,大概看明白意思了,自然会思考在什么情况下用到它。而不是说“不错,这书讲得很好。能否深入些?”
我觉得这篇帖子适合那些需要用到ClassLoader的Java程序员看,我想并不适合每一个Java程序员吧。
整个jar都想热替换, 你不如就hot deploy一把算了, 像jboss与tomcat, 都是整个context初始化一遍的.这个下层是通过什么来实现的呢
自行实现ClassLoader吗?
是的, 重新实例化一个自定义的ClassLoader, 但是, 我测试过, 当你hot deploy后.
老的ClassLoader还是存在的, 就不清楚它什么时候回收了.
可能system class loader还在引用它吧
整个jar都想热替换, 你不如就hot deploy一把算了, 像jboss与tomcat, 都是整个context初始化一遍的.这个下层是通过什么来实现的呢
自行实现ClassLoader吗?
整个jar都想热替换, 你不如就hot deploy一把算了, 像jboss与tomcat, 都是整个context初始化一遍的.
正解,部署和组件开发!!!
自己没用过就算了。。。也好意思拿出来说。你不接触新的东西,永远不知道自己的无知
我们看到上面两个方法声明,第二个方法的第二个参数是用于设置加载类的时候是否连接该类,true就连接,否则就不连接。
说到连接,不得不在此做一下解释,在JVM加载类的时候,需要经过三个步骤,装载、连接、初始化。装载就是找到相应的class文件,读入JVM,初始化就不用说了,最主要就说说连接。
连接分三步,第一步是验证class是否符合规格,第二步是准备,就是为类变量分配内存同时设置默认初始值,第三步就是解释,而这步就是可选的,根据上面loadClass方法的第二个参数来判定是否需要解释
这里讲错了吧,你自己都说第2个参数是用于确定返回的Class是否是已经连接的,怎么又说第二个参数是用来判定是否需要解析?解析是可选的,连接不一定包含解析的。第2个参数如果是true,返回的class一定是已经连接的(是否解析取决于JVM的实现),如果是false,返回的是可能是连接的(不是初次),也可能是没有连接的(第一次)。
都直接继承了ClassLoader,那就是平级的啊,不是父子类的关系。
JVM会自动识别类的继承和实现关系,保证父类先于子类或者接口类先于实现类加载。
blogbin
都直接继承了ClassLoader,那就是平级的啊,不是父子类的关系。
要深入了解ClassLoader,首先就要知道ClassLoader是用来干什么的,顾名思义,它就是用来加载Class文件到JVM,以供程序使用的。我们知道,java程序可以动态加载类定义,而这个动态加载的机制就是通过ClassLoader来实现的,所以可想而知ClassLoader的重要性如何。
看到这里,可能有的朋友会想到一个问题,那就是既然ClassLoader是用来加载类到JVM中的,那么ClassLoader又是如何被加载呢?难道它不是java的类?
没有错,在这里确实有一个ClassLoader不是用java语言所编写的,而是JVM实现的一部分,这个ClassLoader就是bootstrap classloader(启动类加载器),这个ClassLoader在JVM运行的时候加载java核心的API以满足java程序最基本的需求,其中就包括用户定义的ClassLoader,这里所谓的用户定义是指通过java程序实现的ClassLoader,一个是ExtClassLoader,这个ClassLoader是用来加载java的扩展API的,也就是/lib/ext中的类,一个是AppClassLoader,这个ClassLoader是用来加载用户机器上CLASSPATH设置目录中的Class的,通常在没有指定ClassLoader的情况下,程序员自定义的类就由该ClassLoader进行加载。
当运行一个程序的时候,JVM启动,运行bootstrap classloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。
上面大概讲解了一下ClassLoader的作用以及一个最基本的加载流程,接下来将讲解一下ClassLoader加载的方式,这里就不得不讲一下ClassLoader在这里使用了双亲委托模式进行类加载。
每一个自定义ClassLoader都必须继承ClassLoader这个抽象类,而每个ClassLoader都会有一个parent ClassLoader,我们可以看一下ClassLoader这个抽象类中有一个getParent()方法,这个方法用来返回当前ClassLoader的parent,注意,这个parent不是指的被继承的类,而是在实例化该ClassLoader时指定的一个ClassLoader,如果这个parent为null,那么就默认该ClassLoader的parent是bootstrap classloader,这个parent有什么用呢?
我们可以考虑这样一种情况,假设我们自定义了一个ClientDefClassLoader,我们使用这个自定义的ClassLoader加载java.lang.String,那么这里String是否会被这个ClassLoader加载呢?事实上java.lang.String这个类并不是被这个ClientDefClassLoader加载,而是由bootstrap classloader进行加载,为什么会这样?实际上这就是双亲委托模式的原因,因为在任何一个自定义ClassLoader加载一个类之前,它都会先委托它的父亲ClassLoader进行加载,只有当父亲ClassLoader无法加载成功后,才会由自己加载,在上面这个例子里,因为java.lang.String是属于java核心API的一个类,所以当使用ClientDefClassLoader加载它的时候,该ClassLoader会先委托它的父亲ClassLoader进行加载,上面讲过,当ClassLoader的parent为null时,ClassLoader的parent就是bootstrap classloader,所以在ClassLoader的最顶层就是bootstrap classloader,因此最终委托到bootstrap classloader的时候,bootstrap classloader就会返回String的Class。
我们来看一下ClassLoader中的一段源代码:
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // 首先检查该name指定的class是否有被加载 Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { //如果parent不为null,则调用parent的loadClass进行加载 c = parent.loadClass(name, false); } else { //parent为null,则调用BootstrapClassLoader进行加载 c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { //如果仍然无法加载成功,则调用自身的findClass进行加载 c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }
从上面一段代码中,我们可以看出一个类加载的大概过程与之前我所举的例子是一样的,而我们要实现一个自定义类的时候,只需要实现findClass方法即可。
为什么要使用这种双亲委托模式呢?
第一个原因就是因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
第二个原因就是考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的ClassLoader。
上面对ClassLoader的加载机制进行了大概的介绍,接下来不得不在此讲解一下另外一个和ClassLoader相关的类,那就是Class类,每个被ClassLoader加载的class文件,最终都会以Class类的实例被程序员引用,我们可以把Class类当作是普通类的一个模板,JVM根据这个模板生成对应的实例,最终被程序员所使用。
我们看到在Class类中有个静态方法forName,这个方法和ClassLoader中的loadClass方法的目的一样,都是用来加载class的,但是两者在作用上却有所区别。
Class<?> loadClass(String name)
Class<?> loadClass(String name, boolean resolve)
我们看到上面两个方法声明,第二个方法的第二个参数是用于设置加载类的时候是否连接该类,true就连接,否则就不连接。
说到连接,不得不在此做一下解释,在JVM加载类的时候,需要经过三个步骤,装载、连接、初始化。装载就是找到相应的class文件,读入JVM,初始化就不用说了,最主要就说说连接。
连接分三步,第一步是验证class是否符合规格,第二步是准备,就是为类变量分配内存同时设置默认初始值,第三步就是解释,而这步就是可选的,根据上面loadClass方法的第二个参数来判定是否需要解释,所谓的解释根据《深入JVM》这本书的定义就是根据类中的符号引用查找相应的实体,再把符号引用替换成一个直接引用的过程。有点深奥吧,呵呵,在此就不多做解释了,想具体了解就翻翻《深入JVM吧》,呵呵,再这样一步步解释下去,那就不知道什么时候才能解释得完了。
我们再来看看那个两个参数的loadClass方法,在JAVA API 文档中,该方法的定义是protected,那也就是说该方法是被保护的,而用户真正应该使用的方法是一个参数的那个,一个参数的loadclass方法实际上就是调用了两个参数的方法,而第二个参数默认为false,因此在这里可以看出通过loadClass加载类实际上就是加载的时候并不对该类进行解释,因此也不会初始化该类。而Class类的forName方法则是相反,使用forName加载的时候就会将Class进行解释和初始化,forName也有另外一个版本的方法,可以设置是否初始化以及设置ClassLoader,在此就不多讲了。
不知道上面对这两种加载方式的解释是否足够清楚,就在此举个例子吧,例如JDBC DRIVER的加载,我们在加载JDBC驱动的时候都是使用的forName而非是ClassLoader的loadClass方法呢?我们知道,JDBC驱动是通过DriverManager,必须在DriverManager中注册,如果驱动类没有被初始化,则不能注册到DriverManager中,因此必须使用forName而不能用loadClass。
通过ClassLoader我们可以自定义类加载器,定制自己所需要的加载方式,例如从网络加载,从其他格式的文件加载等等都可以,其实ClassLoader还有很多地方没有讲到,例如ClassLoader内部的一些实现等等,本来希望能够讲得简单易懂一点,可是结果自己看回头好像感觉并不怎么样,郁闷,看来自己的文笔还是差太多了,希望能够给一些有需要的朋友一点帮助吧。
评论
30 楼
qmy
2007-09-25
收回上面的话。。。
我错了
- -!!
我错了
- -!!
29 楼
qmy
2007-09-18
yfmine 写道
alibubu 写道
每当有一些类似于这样的文章发表时,后面总会跟着一批貌似很明白的人,说着一些类似于“讲的很好”,“不错,能否讲深点”的话,好像只有这样才显示出自己的高深。悲叹啊。
对于classloader,在项目中有谁会用到?我看对于自定义classloader,恐怕也只有在需要对class进行加密后,在classloader级进行class解密才能用得到,而这,又有几个项目需要?还不如多花点时间搞点别的。
非常反感一些人的高深。我不是针对楼主。
对于classloader,在项目中有谁会用到?我看对于自定义classloader,恐怕也只有在需要对class进行加密后,在classloader级进行class解密才能用得到,而这,又有几个项目需要?还不如多花点时间搞点别的。
非常反感一些人的高深。我不是针对楼主。
还是您老高深……
alibubu说得是,我比较同意,我是在百度上搜索“什么时候需要用到ClassLoader”的时候搜索到这个帖子的。我正在看《深入Java虚拟机》,第3章讲了ClassLoader,我看完了觉得有必要弄清楚什么时候需要用到ClassLoader,因为我看了书上写的一大堆,大概看明白意思了,自然会思考在什么情况下用到它。而不是说“不错,这书讲得很好。能否深入些?”
我觉得这篇帖子适合那些需要用到ClassLoader的Java程序员看,我想并不适合每一个Java程序员吧。
28 楼
galaxystar
2007-08-27
Groovy 写道
galaxystar 写道
Groovy 写道
那么如果想在程序中动态的reload某个jar(这个jar文件在硬盘上可能已经被替换了)应该如何做呢
整个jar都想热替换, 你不如就hot deploy一把算了, 像jboss与tomcat, 都是整个context初始化一遍的.
自行实现ClassLoader吗?
是的, 重新实例化一个自定义的ClassLoader, 但是, 我测试过, 当你hot deploy后.
老的ClassLoader还是存在的, 就不清楚它什么时候回收了.
可能system class loader还在引用它吧
27 楼
Groovy
2007-08-27
galaxystar 写道
Groovy 写道
那么如果想在程序中动态的reload某个jar(这个jar文件在硬盘上可能已经被替换了)应该如何做呢
整个jar都想热替换, 你不如就hot deploy一把算了, 像jboss与tomcat, 都是整个context初始化一遍的.
自行实现ClassLoader吗?
26 楼
galaxystar
2007-08-27
Groovy 写道
那么如果想在程序中动态的reload某个jar(这个jar文件在硬盘上可能已经被替换了)应该如何做呢
整个jar都想热替换, 你不如就hot deploy一把算了, 像jboss与tomcat, 都是整个context初始化一遍的.
25 楼
Groovy
2007-08-27
那么如果想在程序中动态的reload某个jar(这个jar文件在硬盘上可能已经被替换了)应该如何做呢
24 楼
galaxystar
2007-08-27
楼主有没有研究过, 类的卸载或重载(非jvm ti支持的redefine class, 那个只能改方法体, 不能新增, 删除方法).
据我所知, 必须创建一个新的ClassLoader,
这对于实现hot swap是非常麻烦的.
因为老的引用当前类, 是在老的ClassLoader上.
必须将所有引用类都初始化!
据我所知, 必须创建一个新的ClassLoader,
这对于实现hot swap是非常麻烦的.
因为老的引用当前类, 是在老的ClassLoader上.
必须将所有引用类都初始化!
23 楼
zhoulf
2007-08-27
引用
leadyu 2007-06-25 20:14
父子委托机制,是一种classloader实现的标准,但是并没有强制的限定自定义的classloader一定要遵循这种机制,比如weblogic就可以配置classloader模型。
但是这种机制,保证了两点,一,保证了安全性,二,保证了每个classloader的边界,就是说不该你加载的类你不要去加载,否则我们知道不同的classloader都有其命名空间,保证一个类只被其中一个classloader加载,否则系统就会有多个版本的类存在,这种边界在中间件里是非常重要的。
了解classloader对于高级程序员我觉得是非常有用的,虽然我们日常非常少用到它,但是了解它的机制,对于解决很多部署问题非常有帮助,比如部署EJB过程出现的问题,以及其他的一些东西。
另外在自己实现一些组件的时候也可能应用到这方面的技术。
父子委托机制,是一种classloader实现的标准,但是并没有强制的限定自定义的classloader一定要遵循这种机制,比如weblogic就可以配置classloader模型。
但是这种机制,保证了两点,一,保证了安全性,二,保证了每个classloader的边界,就是说不该你加载的类你不要去加载,否则我们知道不同的classloader都有其命名空间,保证一个类只被其中一个classloader加载,否则系统就会有多个版本的类存在,这种边界在中间件里是非常重要的。
了解classloader对于高级程序员我觉得是非常有用的,虽然我们日常非常少用到它,但是了解它的机制,对于解决很多部署问题非常有帮助,比如部署EJB过程出现的问题,以及其他的一些东西。
另外在自己实现一些组件的时候也可能应用到这方面的技术。
正解,部署和组件开发!!!
22 楼
zhoulf
2007-08-27
引用
每当有一些类似于这样的文章发表时,后面总会跟着一批貌似很明白的人,说着一些类似于“讲的很好”,“不错,能否讲深点”的话,好像只有这样才显示出自己的高深。悲叹啊。
对于classloader,在项目中有谁会用到?我看对于自定义classloader,恐怕也只有在需要对class进行加密后,在classloader级进行class解密才能用得到,而这,又有几个项目需要?还不如多花点时间搞点别的。
非常反感一些人的高深。我不是针对楼主。
对于classloader,在项目中有谁会用到?我看对于自定义classloader,恐怕也只有在需要对class进行加密后,在classloader级进行class解密才能用得到,而这,又有几个项目需要?还不如多花点时间搞点别的。
非常反感一些人的高深。我不是针对楼主。
自己没用过就算了。。。也好意思拿出来说。你不接触新的东西,永远不知道自己的无知
21 楼
dennis_zane
2007-06-26
calmness 写道
我们看到上面两个方法声明,第二个方法的第二个参数是用于设置加载类的时候是否连接该类,true就连接,否则就不连接。
说到连接,不得不在此做一下解释,在JVM加载类的时候,需要经过三个步骤,装载、连接、初始化。装载就是找到相应的class文件,读入JVM,初始化就不用说了,最主要就说说连接。
连接分三步,第一步是验证class是否符合规格,第二步是准备,就是为类变量分配内存同时设置默认初始值,第三步就是解释,而这步就是可选的,根据上面loadClass方法的第二个参数来判定是否需要解释
这里讲错了吧,你自己都说第2个参数是用于确定返回的Class是否是已经连接的,怎么又说第二个参数是用来判定是否需要解析?解析是可选的,连接不一定包含解析的。第2个参数如果是true,返回的class一定是已经连接的(是否解析取决于JVM的实现),如果是false,返回的是可能是连接的(不是初次),也可能是没有连接的(第一次)。
20 楼
yananay
2007-06-26
讲的太简单了。
具体到应用服务器里,例如EJB环境,一个 ear 里有war, 等等情况,
这些都应该说到.
具体到应用服务器里,例如EJB环境,一个 ear 里有war, 等等情况,
这些都应该说到.
19 楼
leadyu
2007-06-25
父子委托机制,是一种classloader实现的标准,但是并没有强制的限定自定义的classloader一定要遵循这种机制,比如weblogic就可以配置classloader模型。
但是这种机制,保证了两点,一,保证了安全性,二,保证了每个classloader的边界,就是说不该你加载的类你不要去加载,否则我们知道不同的classloader都有其命名空间,保证一个类只被其中一个classloader加载,否则系统就会有多个版本的类存在,这种边界在中间件里是非常重要的。
了解classloader对于高级程序员我觉得是非常有用的,虽然我们日常非常少用到它,但是了解它的机制,对于解决很多部署问题非常有帮助,比如部署EJB过程出现的问题,以及其他的一些东西。
另外在自己实现一些组件的时候也可能应用到这方面的技术。
但是这种机制,保证了两点,一,保证了安全性,二,保证了每个classloader的边界,就是说不该你加载的类你不要去加载,否则我们知道不同的classloader都有其命名空间,保证一个类只被其中一个classloader加载,否则系统就会有多个版本的类存在,这种边界在中间件里是非常重要的。
了解classloader对于高级程序员我觉得是非常有用的,虽然我们日常非常少用到它,但是了解它的机制,对于解决很多部署问题非常有帮助,比如部署EJB过程出现的问题,以及其他的一些东西。
另外在自己实现一些组件的时候也可能应用到这方面的技术。
18 楼
realreal2000
2007-06-25
王森的那本深入java2,里面介绍了classloader,写得不错,例子也有说服性
17 楼
pioneer21th
2007-06-23
问个问题,根据ClassLoader的代码,貌似用户自定义的类不是由bootstrap Loader加载就是由App Loader加载,因为那个parent.loadClass是一个递归调用,最终会到APP 的ClassLoader方法,而自定义的ClassLoader只是起到找到Class文件的作用,不知道这样理解可否正确?
还有APP ClassLoader是在何时指定的?
还有APP ClassLoader是在何时指定的?
16 楼
blogbin
2007-06-23
calmness 写道
dlovek 写道
本身有两个类继承了ClassLoader,怎么保证两个子类之间哪个是父类?1
都直接继承了ClassLoader,那就是平级的啊,不是父子类的关系。
JVM会自动识别类的继承和实现关系,保证父类先于子类或者接口类先于实现类加载。
blogbin
15 楼
jiakechong
2007-06-08
楼主分享,,
深入java虚拟机,那本书有讲
深入java虚拟机,那本书有讲
14 楼
calmness
2007-06-06
dlovek 写道
本身有两个类继承了ClassLoader,怎么保证两个子类之间哪个是父类?1
都直接继承了ClassLoader,那就是平级的啊,不是父子类的关系。
13 楼
zhkchi
2007-06-06
起码大致知道是怎么回事了,谢谢
12 楼
dlovek
2007-06-05
本身有两个类继承了ClassLoader,怎么保证两个子类之间哪个是父类?1
11 楼
davexin
2007-06-05
讲的不太清楚,ClassLoader用的太多了,对不太了解的人,就像看绕口令一样。
发表评论
-
使用java实现http多线程下载
2008-07-27 12:09 20595下载工具我想没有几个人不会用的吧,前段时间比较无聊,花 ... -
使用JAVA通过ARP欺骗实现数据封包监听
2008-07-23 16:12 3655如果说最近有 ... -
JPA,感觉有点鸡肋
2007-12-07 22:14 2199看了下JPA的介绍,就是在原有ORM的基础上抽象出一层 ... -
DAO与SERVICE层的疑惑
2007-11-30 23:32 8209一直以来都是开发EJB的项目,对于SSH的架构仅仅只是 ... -
Dao控制事务设想,线程级事务处理
2007-11-23 22:32 1554最近在重构公司的一个项目,在事务处理的问题上挺伤脑筋,主要就是 ... -
Re: 关于Spring中的父容器和子容器
2007-05-22 15:03 3469protected WebApplicationCont ... -
框架设计时强制性依赖以及非依赖式约定的考虑
2007-05-01 13:25 2980在框架的设计中,例如struts,我们知道对于每个用户 ... -
spring源码分析-XmlBeanFactory导读
2007-04-26 18:16 8263源代码分析,是一件既痛苦又快乐的事情,看别人写的代码是通过的, ... -
关于接口暴露问题的解决思路
2007-04-19 21:32 6763前一两天在讨论群里,我提出过一个关于接口暴露的问题与群友们进行 ... -
到底该如何去设计?
2007-04-11 20:30 4478在一些软件项目当 ... -
spring jpetstore研究入门—完结篇
2007-04-10 22:44 6868上一文安装篇讲述了如何把jpetstore导入netbeans ... -
spring jpetstore研究入门—安装篇
2007-04-09 22:43 7154之所以写这个jpetstore研究入门的文章,是为了给茫然不知 ... -
java新人最佳选择,netbeans轻松部署应用
2007-04-08 01:39 2881相信很多新手朋友们对J2EE应用环境的配置以及工具的使 ...
相关推荐
2. **配置环境和类加载器**:`LoggingApplicationListener`会获取到`ConfigurableEnvironment`和`ClassLoader`对象,这允许它根据当前应用的环境和类加载器来设置日志系统。 3. **初始化日志系统**:`...
以下是对`refresh()`方法及其内部重要步骤的详细解读: 1. **prepareRefresh()**: 这个方法首先被调用,用于准备上下文进行刷新。它可能包含一些预处理操作,如设置刷新开始时间,准备环境等。 2. **...
Java学习杂谈系列涵盖了许多关于Java编程的基础概念和机制,以下是对这些知识点的详细解读: 1. **动态加载机制**: 动态加载机制是Java语言的一个关键特性,它使得程序在运行时才能确定哪些类需要加载。当你声明...
在提供的文档"java类加载机制.doc"中,应该会详细阐述这些概念,并可能包含实例分析和源码解读,帮助读者更好地理解和应用Java类加载机制。对于希望优化系统性能或进行底层优化的开发者来说,这是一个不可多得的学习...
1. 类加载器(ClassLoader):理解类如何被加载到JVM中,以及类加载的双亲委派模型。 2. 集合框架(Collections Framework):如ArrayList、LinkedList、HashMap等数据结构的实现,以及它们的性能特点。 3. 多线程...
最后,Druid的源码中还体现了多种语言特性,比如Interface和Abstract的使用,FunctionP的实现,ClassLoader的运用,以及ThreadExecutes和ThreadLocal的应用。这些语言特性的应用有助于构建出高效和线程安全的代码。 ...
1. 类加载机制:`java.lang.ClassLoader`是Java中负责加载类的类,理解其工作原理有助于我们了解类如何被找到并加载到JVM中,这对于理解和实现自定义类加载器非常重要。 2. 集合框架:深入源码可以让我们明白`...
基础类加载器包括Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader,它们协同工作,确保类的正确加载。 2. **字节码验证**:JVM在执行字节码之前会进行验证,确保代码的安全性,防止恶意...
#### 三、Java执行过程深入解读 Java程序的执行过程涉及到了JVM的内存模型和执行引擎,主要包括以下几个方面: 1. **内存模型**: - **程序计数器**:线程私有的,用来记录当前线程所执行的字节码指令的地址。 -...
- **源码解读**:深入分析`ClassLoader`的核心代码,包括`loadClass`方法等关键部分,掌握类加载过程中的细节。 - **实战案例**:通过具体案例来演示如何利用`ClassLoader`解决实际问题,比如热部署等场景的应用。 ...
类加载器负责将类的二进制数据加载到JVM中,是Java多级加载机制的核心组件,包括Bootstrap ClassLoader、Extension ClassLoader和System ClassLoader,各自负责不同类型的类加载。 ### XML解析技术 XML(可扩展标记...
实现插件化的重点在于对Android四大组件和资源加载流程的分析和解读。插件化代码的编写,涉及到的知识点主要有java中的反射,动态代理,静态代理以及android中的AIDL跨进程通信,binder机制,ClassLoader加载机制,...
- 类的加载通常遵循双亲委派模型,即从顶层的Bootstrap ClassLoader开始,如果找不到,则交给Extension ClassLoader,再找不到则由AppClassLoader加载,最后是自定义的类加载器。 5. **垃圾回收与对象的生命周期**...
源码解读有助于理解TCP和UDP连接的建立、数据传输过程。 7. **反射API**:`java.lang.reflect`包包含用于运行时动态访问和修改类的API。通过源码学习,我们可以掌握如何通过反射创建对象、调用方法、访问字段,以及...
根据提供的文件信息,我们可以从中提炼出与Java相关的多个知识点,并对其进行详细解读: ### 1. Java中的异常处理 - **概念介绍**:Java中的异常处理机制是程序设计中非常重要的一部分,它可以帮助程序员有效地...
以下是对这些面试题的详细解读: 一、红黑树的特性: 红黑树是一种自平衡的二叉查找树,其特性包括: 1. 节点颜色要么是红色要么是黑色。 2. 根节点是黑色。 3. 所有叶子节点(NIL节点,空节点)是黑色。 4. 如果一...
#### 第一章 解读API 1. **Object常用的方法**:包括wait(), notify(), finalize(), equals(), toString(), hashCode()等。 2. **String与StringBuffer的区别**:String是不可变对象,StringBuffer是可变对象。 3. *...
以下是对给定标题和描述的详细解读。 首先,`GetJarFile.java`是实现这个功能的主要类。在Java中,我们通常使用`java.util.jar.JarFile`类来处理JAR文件。以下是读取JAR内资源的基本步骤: 1. **打开JAR文件**: ...