前言 了解JAVA的类装载器 Java 编程语言编译器把源代码代码转换成为一个假定机器(即虚拟机)上的 机器语言虚拟机代码保存在一个后缀为class的类文件中每个类文件保存这 个类的所有方法的虚拟机代码 当运行时用一个解释程序解释这些类文件把这些文件内的虚拟机指信信令翻 译成本地的机器语言分存内存确定程序入口点 类装载器功能类似与C中调入dll文件文法在C中是调入dll文件分配内存确定 程序入口点(分配入口指针)而在java中调入一个class文件同样是从本地或网络 中调入文件转换为本地机器代码分配内存确定程序入口点 当我们在使用中有时要使用一个新类知道它的文件路径和它的文件名字我们 要把它调入系统并使用它或者说一个类文件已经被加密处理类文件里面的内容 是我们加密后的密文不能直接使用只能是对文件内容解密后才能使用就可 以用类库加载器ClassLoader把类文件当做数据流读入到一个byte[]中对 这个 byte[]进行解密处理后(没加密当然就不用做这步了)再通过 byte[] 生成一个类并加载到系统中 对于使用中有以下两种方法 方法 使用接口类新调用的class是对它的具体实现 ) 写一个接口类 newfaceclass public interface newface { public void out(String xx); public int outsize(String xString x); } ) 写接口文件实现 testfaceaclass 并更名为 testfaceafile 或其它文件名全可以 /* newface的实现 */ public class testfacea implements newface{ public void out(String xx) { Systemoutprintln(xx+ for testfacea ); } public int outsize(String xString x) { return xlength()+xlength();; } } 执行的的命令 javac testfaceajava ren testfaceaclass testfaceafile ) 在主程序中调入文件到byte[]中可以在文件可以在本地也可用网络无论如何只要能将编译后的文件内容的类代码放到 byte[]当中就可以 javaioFileInputStream in=new javaioFileInputStream(namefile); byte[] classbyte=new byte[maxsize]; ) 转换成一个Class并初始化 return defineClass(classnameclassbytereadsize); ) 实现接口 实际上就是对一个接口类用调入的文件实现当然可以用不同的文件进行不同的实现也可以对一个文件进行加解密操作 //方法 的例子代码newface是本地接口类newfaceclass本地已经存在 开始 testc=clload(testfaceafiletestfacea); testo=testcnewInstance(); ((newface)testo)out(方法 第()种使用方法); Systemoutprintln(outsize=+((newface)testo)outsize(aaaa)); 或 testc=clload(testfaceafisletestfacea); testo=testcnewInstance(); newface newface=(newface)testo; newfaceout(方法 第()种使用方法); Systemoutprintln(outsize=+newfaceoutsize(bbbbb)); 要注意的是对一个要调入的文件一定要是一个已经存在的接口类的实现这个有点EJB中的调用的中远程接口要在本地而调入的文件就是EJBobject了这种方法的的好处是要调入的class中的方法是可以说是已知的相对来讲这种方法简明易用以下是主程序的完整代码 //使用的主程序 public class testnewface { public static void main(String[] args) throws javalangException { // 共用初使化参数开始 Class testc; Object testo; cloader cl=new cloader(); // 共用初使化参数结束 //方法 的例子代码newface是本地接口类newfaceclass本地已经存在 开始 testc=clload(testfaceafiletestfacea); testo=testcnewInstance(); ((newface)testo)out(方法 第()种使用方法); Systemoutprintln(outsize=+((newface)testo)outsize(aaaa)); testc=clload(testfaceafisletestfacea); testo=testcnewInstance(); newface newface=(newface)testo; newfaceout(方法 第()种使用方法); Systemoutprintln(outsize=+newfaceoutsize(bbbbb)); //方法 的例子代码结束 } } /* 要想自己完成从一个 byte[] 转换到一个Class 必须要 extends ClassLoader 因为ClassLoader中的方法defineClass是 protected 要使用只有 extends ClassLoader */ class cloader extends ClassLoader { static int maxsize=; public Class load(String namefileString classname) throws javalangException { try { //进行判断这个class是否已经调入已经有就直接返回不然就调入 Class ctmp=thisfindLoadedClass(classname); Systemoutprintln(ctmpgetName()+ is load); return ctmp; } catch (Exception e) { //Systemoutprintln(e); } javaioFileInputStream in=new javaioFileInputStream(namefile); byte[] classbyte=new byte[maxsize]; //实际应用时完全可以对一个文件进行加解密处理只要保证使用defineClass时classbyte中 //已经解密后的内容就可以 int readsize; readsize=inread(classbyte); // Systemoutprintln(读文件长:+readsize); inclose(); return defineClass(classnameclassbytereadsize); } } 方法 不使用本地接口类的方法这种方法class从文件定义成一个class和方法是相同的但要使用这个class就不同了这种方法不需要接口类 ) 写一个类 testfaceaclass (本例中为了方便还是使用了testfacea实际上已经可以不用 implements newface即可以完全不用接口类) public class testfacea { public void out(String xx) { Systemoutprintln(xx+ for testfacea ); } public int outsize(String xString x) { return xlength()+xlength();; } } 为明析起见还有一个测试用类型一个列系统信息表的类 public class listinfo { public static void main(String[] args) { //列系统信息表 begin String skeysinfo; Object so; javautilEnumeration hlistkey=SystemgetProperties()propertyNames(); while (hlistkeyhasMoreElements()) { skey=(String)hlistkeynextElement(); so=SystemgetProperty(skey); Systemoutprintln(key=+skey+ info=+so); } //列系统信息表 end } } ) 生成 testfaceaclass 更名为 testfaceafile 或其它文件名也可以 生成 listinfoclass 更名为 listinfofile 或其它文件名也可以 执行的的命令 javac testfaceajava ren testfaceaclass testfaceafile javac listinfojava ren listinfoclass listinfofile ) 主程序中调入文件到byte[]中可以在本地文件调用也可用网络无论如何只要能将 |