A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 赵亚威 于 2013-4-9 23:01 编辑

defineClass(),loadClass(),findClass()它们有什么区别?委托机制是谁具有的 还是有的有委托机制 有的没有这一特性

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 25分咯~

查看全部评分

5 个回复

倒序浏览
呵呵 算是吧 再做入学测试
回复 使用道具 举报
就最近的理解情况,希望能给你的帮助
loadClass();是加载 类名.class 字节码文件的工具

findClass();是类加载器在JVM内部实现查找指定路径下的 . class 文件的机制,BootStrap ,ExtClassLoader,AppClassLoader,按照这个顺序查找,有就给JVM加载,没有就往下找, 在基础加强里,张老师 就是复写了该方法,将指定目录下的字节码文件,通过ByteArrayOutputStream 解密后的字节码文件,给JVM 去加载,实现解密的过程

defineClass();是将你定义的字节码文件经过字节数组流解密之后,将该字节流数组生成字节码文件,也就是该类的 文件的类名.class,
注意一点,视频里用的是过时的方法,defineClass( byte[] b ,0, b.length) ,这样生成的字节码就是默认的字节码文件。
他的替代方法是 defineClass(String name  , byte[]  b , 0, b.length ),声明时,name 是指定该类名,这里的类名是指包含它所属的 包名+类名

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报 0 1
本帖最后由 李罡 于 2013-4-9 15:40 编辑

我的理解是:
CLassLoader类中loadClass的具体实现
(1)查看请求的类装载器是否已经被装载进这个类装载器的命名空间。如果确实如此,返回这个已经装载的Class实例。
(2)否则调用委托机制,如果父类加载成功,则返回这个Class实例。
(3)否则,调用findClass(),findClass会试图寻找或生成一个字节数组。如果成功,findClass()把字节数组传递给defineClass,后者试着导入这个类型,返回一个Class实例。如果findClass返回了一个Class实例,loadClass()把这个实例返回。
(4)否则,findClass抛出某些异常,loadClass返回同样异常。

loadClass()方法里面分为两部分:
第一部分是主要流程:即把一个类加载进内存的时候它要先去一级一级地找父类,看父类能不能加载,如果父类能加载的话,就不用再返回到该类了让该类加载,这部分相当于委托机制。
第二部分是部分细节:就是如果由该类自己加载该怎么加载。也就是findClass()部分。(这些老师上课说过一些)

loadClass()方法相当于采用了模板设计模式,
public abstract class ClassLoader{
private loadClass(){
....//loadClass()中的主要流程
findClass();//loadClass()中的部分细节。
}
public abstract findClass();
}

所以我们自定义加载器只需复写ClassLoader类中的findClass()方法就行了~~

主要方向:loadClass()-->findClass(String name)-->defineClass(String name,byte[] bytes, off, len)

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
杨玉辉 发表于 2013-4-9 10:43
就最近的理解情况,希望能给你的帮助
loadClass();是加载 类名.class 字节码文件的工具

虽然loadClass和findClass我不是很清楚你说得是否是对的,但是defineClass显然你理解是错误的,defineClass是将符合class文件格式的字节数组加载到内存当中,从而生成class对象。而不是像你说得生成字节码文件,而defineClass的好处就是类加载器不需要管你的class是怎么来的,你可以从网络中获取,也可以从本地文件中获取,你只要提供符合class格式的字节数组,它就能正确的生成class对象
回复 使用道具 举报
做下源码注释的搬运工。
  ClassLoader loader = new NetworkClassLoader(host, port);
*   Object main = loader.loadClass("Main", true).newInstance();
  * <blockquote><pre>
*     class NetworkClassLoader extends ClassLoader {
*         String host;
*         int port;
*
*         public Class findClass(String name) {
*             byte[] b = loadClassData(name);
*             return defineClass(name, b, 0, b.length);
*         }
*
*         private byte[] loadClassData(String name) {
*             // load the class data from the connection
*             &nbsp;.&nbsp;.&nbsp;.
*         }
*     }
* </pre></blockquote>
总结下就是李罡说的对,这里需要理解的是loadClass返回一个是java.lang.class的实例,findClass里获得二进制字节数组,并调用defineClass方法生成java.lang.class的实例。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马