熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

在運行時刻從文件中調入Class

2013-11-15 11:36:51  來源: JSP教程 

  前言
  
  了解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[]中可以在本地文件調用也可用網絡無論如何只要能將
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19297.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.