锁定老帖子 主题:classloader相关基础知识
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-09-26
jvm是jre里头一个动态连接函数库,jdk里面的jre一般用于运行java本身的程序,比如javac,等等.programfiles下面的jre用于运行用户编写的java程序. JRE下的bin\client 或者 bin\server 的jvm.dll就是JVM了 当一台机器上有多个jvm可选择的时候,jvm的选择步骤: 1)当前目录有没有jre目录(不准确), 2)父目录下的jre子目录 3)注册表HEKY_LOCAL_MACHINE\SoftWare\Java\Java Runtime Environment\ 所以当运行的是jdk\bin\java.exe的时候,用的jre是bin的父目录jdk下面的jre\ 运行java.exe找到了jre后有一个验证程序,验证jre和java.exe的版本是否一致,如果不一致则会发生错误
只有实例化一个类才会被classloader载入,仅仅申明并不会载入
1)implicit隐式,即利用实例化才载入的特性来动态载入class 2)explicit显式方式,又分两种方式: 1)java.lang.Class的forName()方法 2)java.lang.ClassLoader的loadClass()方法
1)当调用forName(String)载入class时执行,如果调用ClassLoader.loadClass并不会执行.forName(String,false,ClassLoader)时也不会执行. 2)如果载入Class时没有执行static块则在第一次实例化时执行.比如new ,Class.newInstance()操作 3)static块仅执行一次 Class类的实例. >>Class类无法手工实例化,当载入任意类的时候自动创建一个该类对应的Class的实例, >>某个类的所有实例内部都有一个栏位记录着该类对应的Class的实例的位置., >>每个java类对应的Class实例可以当作是类在内存中的代理人.所以当要获得类的信息(如有哪些类变量,有哪些方法)时,都可以让类对应的Class的实例代劳.java的Reflection机制就大量的使用这种方法来实现 >>每个java类都是由某个classLoader(ClassLoader的实例)来载入的,因此Class类别的实例中都会有栏位记录他的ClassLoader的实例,如果该栏位为null,则表示该类别是由bootstrap loader载入的(也称root laoder),bootstrap loader不是java所写成,所以没有实例. 原生方法:forName0()等方法,native修饰符
如实例化一个URLClassLoader. URLClassLoader ucl = new URLClassLoader(new URL[]{new URL("file:/e:/bin/")}),URLClassLoader优先找当前目录,再在url中找.class加载.URL中别忘在最后加"/"表示目录
1)java类可以通过实例.getClass.getClassLoader()得知 2)接口由AppClassLoader(System ClassLoader,可以由ClassLoader.getSystemClassLoader()获得实例)载入 3)ClassLoader类由bootstrap loader载入
jvm建立->初始化动作->产生第一个ClassLoader,即bootstrap loader->bootstrap loader在sum.misc.Launcher类里面的ExtClassLoader,并设定其Parent为null->bootstrap loader载入sun.misc.Launcher$AppClassLoader,并设定其parent为ExtClassLoader(但是AppClassLoader也是由bootstrap loader所载入的)->AppClassLoader载入各个xx.class,xx.class也有可能被ExtclassLoader或者bootstrap loader载入. >>自定义的ClassLoader的.getParent()是AppClassLoader.parent和他的加载器并没有关系 >>ExtClassLoader和AppClassLoader都是URLClassLoader的子类.AppClassLoader的URL是由系统参数java.class.path取出的字符串决定,而java.class.path由 运行java.exe时 的-cp或-classpath或CLASSPATH环境变量决定 >>ExtClassLoader查找的url是系统变量java.ext.dirs,java.ext.dirs默认为jdk\jre\lib\ext >>Bootstrap loader的查找url是sun.boot.class.path >>在程序运行后调用System.setProperty()来改变系统变量并不能改变以上加载的路径,因为classloader读取在System.setProperty之前.sun.boot.class.path是在程序中写死的,完全不能修改 委派模型 当classloader有类需要载入时先让其parent搜寻其搜寻路径帮忙载入,如果parent找不到,在由自己搜寻自己的搜寻路径载入,ClassLoader hierachy本来就有这种性质 NoClassDefFoundError和ClassNotFoundException NoClassDefFoundError:当java源文件已编译成.class文件,但是ClassLoader在运行期间在其搜寻路径load某个类时,没有找到.class文件则报这个错 ClassNotFoundException:试图通过一个String变量来创建一个Class类时不成功则抛出这个异常 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-09-26
刚刚好需要:)
|
|
返回顶楼 | |
发表时间:2006-09-26
哪位达人麻烦一下给打分加入精华吧
|
|
返回顶楼 | |
发表时间:2006-09-26
adamzhao 写道 哪位达人麻烦一下给打分加入精华吧 不错!
|
|
返回顶楼 | |
发表时间:2006-09-26
cedar_1982 写道 adamzhao 写道 哪位达人麻烦一下给打分加入精华吧 不错!对于大多数人没用的空中楼阁没必要精华。。。。。 头次见人求精的帖子 |
|
返回顶楼 | |
发表时间:2006-09-26
抛出异常的爱 写道 cedar_1982 写道 adamzhao 写道 哪位达人麻烦一下给打分加入精华吧 不错!对于大多数人没用的空中楼阁没必要精华。。。。。 头次见人求精的帖子 呵呵,对于理解原理,是有点帮助的! 但是加精应该是多数人都认同的!才可以加精的! JVM,我想搞JAVA的,或多或少都知道些!对于本身,书本上也是有详细介绍的! 所以,支持楼上的! |
|
返回顶楼 | |
发表时间:2006-09-27
抛出异常的爱 写道 cedar_1982 写道 adamzhao 写道 哪位达人麻烦一下给打分加入精华吧 不错!对于大多数人没用的空中楼阁没必要精华。。。。。 头次见人求精的帖子 呵呵,我看了这篇文章之后觉得不错,可惜我还没有权利打分,所以希望有这个权限的可以考虑一下。 无他! |
|
返回顶楼 | |
发表时间:2006-09-27
呵呵
过一阵子就可以打分了 到时候把所有的认为要加精的都加了精爽一把。。。 |
|
返回顶楼 | |
发表时间:2006-09-28
确实不错,这个怎么能算空中楼阁?我看文章很实际并且有用。
我也支持加精! 建议楼主再增加一点路径搜索的说明,这样更详细一点了。 |
|
返回顶楼 | |
发表时间:2006-09-30
整理的不错!感谢
|
|
返回顶楼 | |